package mapping;

import mapping.data.Server;
import mapping.data.IDsQueue;

/**
 * This Thread is a helper thread for the FCFS_MS objects. It is a thread that
 * iterates over the AvailableServers Queue it asks the FCFS_MS object to map a
 * job for the server in the head of that queue.
 * 
 * @author Majd Kokaly
 */
public class FCFS_MS_Thread implements Runnable {

	/**
	 * This flag tells the thread if it is alive or should kill itself.
	 */
	private boolean alive = true;

	/**
	 * A Thread objects that runs this Runnable class.
	 */
	private Thread thisThread;

	/**
	 * The FCFS_MS that this thread helps.
	 */
	private FCFS_MS fcfs_ms;

	/**
	 * A default constructor.
	 * 
	 * @param fcfs_ms
	 *            The FCFS_MS object.
	 */
	public FCFS_MS_Thread(FCFS_MS fcfs_ms) {
		this.setAlive(true);
		this.fcfs_ms = fcfs_ms;
	}

	public synchronized boolean isAlive() {
		return alive;
	}

	public synchronized void setAlive(boolean alive) {
		this.alive = alive;
	}

	/**
	 * This method starts the thread.
	 */
	public void startThread() {
		System.out.println("LPAS Thread started");
		thisThread = new Thread(this);
		thisThread.start();
	}

	/**
	 * This method stops the thread.
	 */
	public void stopThread() {
		this.setAlive(false);
		thisThread.interrupt();
		thisThread = null;
	}

	/**
	 * This thread iterates over the AvailableServer queue and ask the FCFS_MS
	 * object to map them.
	 */
	public void run() {
		Server server = null;
		int serverID;
		IDsQueue<Integer> q = this.fcfs_ms.getMapper().getAvailableServersQueue();

		while (this.isAlive()) {
			if (!q.isEmpty()) {
				serverID = q.peak();
				server = this.fcfs_ms.getMapper().getServersTable().get(serverID);
				/*
				 * Any server in the available queue should satisfy this
				 * condition. Just to be sure that the server is neither busy
				 * nor down.
				 */
				if (server.getNumberOfActiveJobs() == 0
						&& !this.fcfs_ms.getMapper().getServersTable().isServerDown(serverID)) {
					int result = this.fcfs_ms.sendJobForServer(serverID);
					
					if (result < 0) { // Could not send
						try {
							Thread.sleep(100);
						} catch (InterruptedException e) {
							if (!isAlive())
								return;
						}
					}
				}
			} else {
				try {

					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
