
import java.io.DataInputStream;
import java.util.*;


/*
 * Retrieve System parameters for the Mac client
 */

public class MacSystemParameters extends SystemParameters{

	//retrieve cpu usage
	public double getCpu() {
		String result = new String();
		try {
			Runtime rtime = Runtime.getRuntime();
			String[] commands = {"/bin/sh", "-c", "iostat -c 5 |tail -3"};
			Process proc = rtime.exec(commands);
			proc.waitFor();
			DataInputStream in = new DataInputStream(proc.getInputStream());
			byte[] bytes = new byte[128];
			while(in.available() > 0) {
				in.read(bytes);
				result = result.concat(new String(bytes));
			}
		} catch(Exception e) {
			e.printStackTrace();
		}

		String[] results = result.trim().split("\n");
		double[] nums = new double[results.length];
		int tmpnum;
		if(results.length < 3) {
			return -1;
		}
		//results.length should be three
		for(int i = 0; i < 3; i++) {

			String[] tokens = results[i].trim().split(" ");
			try {
				tmpnum = Integer.parseInt(tokens[tokens.length-1]);
				nums[i] = tmpnum;
			} catch(NumberFormatException nfe) {
				nums[i] = 0;
			}
		}
		return (100-getMedian(nums));	
	}


	//Get Battery Remaining
	public int getBateryRemaining() {

		String result = new String();
		try {
			Runtime rtime = Runtime.getRuntime();
			String[] commands = {"/bin/sh", "-c", "system_profiler SPPowerDataType|grep Capacity"};
			Process proc = rtime.exec(commands);

			proc.waitFor();
			DataInputStream in = new DataInputStream(proc.getInputStream());

			byte[] bytes = new byte[128];

			while(in.available() > 0) {
				in.read(bytes);
				result = result.concat(new String(bytes));
			}
		} catch(Exception e) {
			e.printStackTrace();
		}

		int full = 0;
		int remaining = 0;

		String[] results = result.split("\n");

		if(results.length >= 2) {

			if(results[0].trim().startsWith("Full Charge")) {
				String[] fullstr = results[0].split(":");

				if(fullstr.length != 2) {
					return -1;
				}
				try {
					full = Integer.parseInt(fullstr[1].trim());
				} catch(NumberFormatException nfe) {
					return -1;
				}
			}

			if(results[1].trim().startsWith("Remaining Capacity")) {
				String[] remainstr = results[1].split(":");

				if(remainstr.length != 2) {
					return -1;
				}
				try {
					remaining = Integer.parseInt(remainstr[1].trim());
				} catch(NumberFormatException nfe) {
					return -1;
				}
			}
			return (int)(((double)remaining)/full*100);
		}
		return 255;

	}


	//Get power status - plugged in or not
	public int getAc() {
		String result = new String();
		try {
			Runtime rtime = Runtime.getRuntime();
			String[] commands = {"/bin/sh", "-c", "system_profiler SPPowerDataType|grep Connected"};
			Process proc = rtime.exec(commands);

			proc.waitFor();
			DataInputStream in = new DataInputStream(proc.getInputStream());

			byte[] bytes = new byte[128];

			while(in.available() > 0) {
				in.read(bytes);
				result = result.concat(new String(bytes));
			}
		} catch(Exception e) {
			e.printStackTrace();
		}

		String[] results = result.trim().split(":");

		if(results.length == 2) {
			if(results[1].trim().equalsIgnoreCase("Yes")) {
				return 1;
			} else if(results[1].trim().equalsIgnoreCase("No")) {
				return 0;
			}
		}


		return 255;
	}


	//Get the space left on the primary hard drive
	public double getDisk() {

		String result = new String();
		try {
			Runtime rtime = Runtime.getRuntime();
			String[] commands = {"/bin/sh", "-c", "system_profiler |grep Available"};
			Process proc = rtime.exec(commands);

			proc.waitFor();
			DataInputStream in = new DataInputStream(proc.getInputStream());

			byte[] bytes = new byte[128];

			while(in.available() > 0) {
				in.read(bytes);
				result = result.concat(new String(bytes));
			}
		} catch(Exception e) {
			e.printStackTrace();
		}

		String[] results = result.trim().split("\n");
		double available;

		for(int i = 0; i < results.length; i++) {
			//GB, MB, TB?
			//need to double check on formatting
			if(results[i].trim().endsWith("B")) {
				String[] tokens = results[i].trim().split(" ");
				if(tokens.length == 3) {
					try {
						available = Double.parseDouble(tokens[1]);
						//for now -- assume free space is listed in GB
						return (available*1024);
					} catch(NumberFormatException nfe) {
						//try next entry
					}
				}
			}
		}
		return -1;		
	}


	//Get the MAC address
	public String getMACAddress(){

		String result = new String();
		try {
			Runtime rtime = Runtime.getRuntime();
			String[] commands = {"/bin/sh", "-c", "system_profiler SPNetworkDataType | grep 'MAC Address'"};
			Process proc = rtime.exec(commands);

			proc.waitFor();
			DataInputStream in = new DataInputStream(proc.getInputStream());

			byte[] bytes = new byte[128];

			while(in.available() > 0) {
				in.read(bytes);
				result = result.concat(new String(bytes));
			}
		} catch(Exception e) {
			e.printStackTrace();
		}
		String[] results = result.trim().split("\n");
		String[] new_results = results[0].trim().split(" ");
		return new_results[2];

	}


	//Get the time the system has been idle
	public double getIdleTime() {
		String result = new String();
		try {
			Runtime rtime = Runtime.getRuntime();
			String[] commands = {"/bin/sh", "-c", "ioreg -c IOHIDSystem |grep Idle"};
			Process proc = rtime.exec(commands);

			proc.waitFor();
			DataInputStream in = new DataInputStream(proc.getInputStream());

			byte[] bytes = new byte[128];

			while(in.available() > 0) {
				in.read(bytes);
				result = result.concat(new String(bytes));
			}
		} catch(Exception e) {
			e.printStackTrace();
		}

		String[] results = result.trim().split("\n");
		long idle = 0;
		for(int i = (results.length-1); i >= 0; i--) {
			if(results[i].indexOf("IdleTime") != -1) {
				String[] tokens = results[i].trim().split(" ");
				for(int j = 0; j < tokens.length; j++) {
					try {
						idle = Long.parseLong(tokens[j]);
						break;
						//return (idle/1000000000);
					} catch(NumberFormatException nfe) {
						//look at next token
					}
				}
				if(idle != 0) {
					break;
				}
			}
		}
		double idle_div = (idle/1000000);
		return (idle_div);
	}


	public List<Comparable> Scheduler(){
		List<Comparable> list = new ArrayList<Comparable>();
		list.add(getDate());
		list.add(getDateInMilliseconds());
		list.add(getBateryRemaining());
		list.add(getAc());
		list.add(getCpu());
		list.add(getDisk());
		list.add(getConnection());
		list.add(getIdleTime());
		list.add(getMACAddress());
		System.out.println(list);

		return list;	
	}


}



