package mapping;

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

/**
 * 
 * This Thread is a helper thread for the Gcu_MS objects. It is a thread that
 * iterates over the AvailableServers Queue and asks the Gcu_MS object to map a
 * job for the server in the head of that queue.
 * 
 * @author Majd Kokaly
 * 
 */
public class Gcu_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 Gcu_MS that this thread helps.
	 */
	Gcu_MS gcu_ms;

	/**
	 * Defualt constructor
	 * 
	 * @param gcu_ms
	 *            To set the gcu_ms data member.
	 */
	public Gcu_MS_Thread(Gcu_MS gcu_ms) {
		this.setAlive(true);
		this.setGcu_ms(gcu_ms);
	}

	public synchronized boolean isAlive() {
		return alive;
	}

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

	public Gcu_MS getGcu_ms() {
		return gcu_ms;
	}

	public void setGcu_ms(Gcu_MS gcu_ms) {
		this.gcu_ms = gcu_ms;
	}

	/**
	 * 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;
	}

	public void run() {
		Server server = null;
		int serverID;
		IDsQueue<Integer> q = this.getGcu_ms().getMapper().getAvailableServersQueue();
		while (this.isAlive()) {
			if (!q.isEmpty()) {
				serverID = q.peak();
				server = this.getGcu_ms().getMapper().getServersTable().get(serverID);

				/*
				 * Any server in the available queue should satisfy this
				 * condition. Just to be sure that the server is not busy and
				 * nor down.
				 */
				if (server.getNumberOfActiveJobs() == 0
						&& !this.getGcu_ms().getMapper().getServersTable().isServerDown(serverID)) {
					Object obj = this.getGcu_ms().sendJobForServer(serverID);
					if (obj == null) {
						try {

							Thread.sleep(30);
						} catch (InterruptedException e) {
							if (!isAlive())
								return;
						}
					}
				}
			} else { // is empty
				try {
					Thread.sleep(30);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
