package pulling.executing;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.Random;
/**
 * This is a thread which will constantly update the BuiltIn Executer as to the availability of the computer which it
 * will use in turn to calculate the remaining time for a job to be executed
 * 
 * @author Ben Kybartas
 *
 */
public class CPUUsageUpdater_BuiltIn implements Runnable{
	private boolean alive = true;
	private ServerSideExecuter_BuiltIn executer;
	private Random r = new Random();
	
	private void UpdateCPUUsage() throws Exception {
		/*
		double percentage;
		percentage = ((double)(95 + r.nextInt(5)) / 100);
		executer.setIdlePercent(1);
		*/
		StringTokenizer tokenizer;
		Runtime runtime = Runtime.getRuntime();
		// With the defualt values this take 3 seconds
		Process proc = null;
		String os = System.getProperty("os.name");
		
		if (os.equalsIgnoreCase("Linux"))
		{
			proc = runtime.exec("vmstat 1 2");
		}
		else if (os.startsWith("Windows"))
		{
			proc = runtime.exec("Typeperf \"\\Processor(_Total)\\% Idle Time\"");
		}
		else 
		{
			proc = runtime.exec("sar -u " + 1 + " " + 1);
		}
		
		InputStream inputstream = proc.getInputStream();
		InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
		BufferedReader bufferedreader = new BufferedReader(inputstreamreader); // bufferedreader is a buffer of the input
		String line;
		
		if (os.startsWith("Windows"))
		{
			int i = 0;
			String SystemIdle;
			while ((line = bufferedreader.readLine()) != null && i < 3)
			{
				i++;
			}	
			proc.destroy();
			tokenizer = new StringTokenizer(line, ",");
			tokenizer.nextToken();
			SystemIdle = tokenizer.nextToken();
			SystemIdle = SystemIdle.substring(1, SystemIdle.length() - 1);
			executer.setIdlePercent(Double.parseDouble(SystemIdle) / 100);
			return;
		}
		
		else if (os.startsWith("Linux"))
		{
			int i = 0;
			
			while ((line = bufferedreader.readLine()) != null && i < 3)
			{
				i++;
			}
			
			tokenizer = new StringTokenizer(line);
			
			for (int j = 0; j < 14; j++)
			{
				tokenizer.nextToken();
			}
			executer.setIdlePercent(Double.parseDouble(tokenizer.nextToken())/100);
			
		}
		else
		{
			while ((line = bufferedreader.readLine()) != null) 
			{
				if (line.trim().length() > 3 && line.trim().substring(0,7).toLowerCase().equalsIgnoreCase("average") ) 
				{
					tokenizer = new StringTokenizer(line);
					tokenizer.nextToken();
					tokenizer.nextToken();
					if (System.getProperty("os.version").startsWith("10.5.")) // To ignore the %nice entry when executing on Mac OS X version 10.5 (Leopard)
						tokenizer.nextToken();
					tokenizer.nextToken();
					executer.setIdlePercent(Double.parseDouble(tokenizer.nextToken()) / 100);
					return;
				}
			}
		}
	}

	private boolean isAlive()
	{
		return alive;
	}
	
	public void setAlive(boolean Alive)
	{
		this.alive = Alive;	
	}
	
	public CPUUsageUpdater_BuiltIn(ServerSideExecuter_BuiltIn Executer)
	{
		this.executer = Executer;
	}
	
	public void run() 
	{
		while (this.isAlive())
		{
			try 
			{
				UpdateCPUUsage();
				Thread.sleep(500);
				this.setAlive(executer.isAlive());
			} 
			catch (Exception e) 
			{
				e.printStackTrace();
			}
		}
		
	}
	
}
