
import org.apache.log4j.Logger;
import org.hyperic.sigar.ProcCpu;
import org.hyperic.sigar.ProcUtil;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Tlhelp32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.win32.W32APIOptions;

/**
 * Check the CPU to find out if the page has finished loading.
 * 
 * @author JPR
 *
 */
public class CPUController
{

	static Logger logger = Logger.getLogger(CPUController.class.getName());
	/**
	 * Constructor
	 */
	public CPUController()
	{
	}

	/**
	 * return the percentage of CPU usage
	 * 
	 * @param page
	 *            used in logs
	 * @return the percentage of CPU usage
	 */
	public double getCpu() throws ErrorException
	{

		int accrobatPID=getAcrobatPID();

		double cpu; // I'm searching for acrobat and explorer cpu
		double maxCpu; // To check if there's some value in cpu reading
		int watchDog = 0; // to detect about infinite loop
		do
		{
			maxCpu = 0.0f;
			cpu = 0.0f;
			logger.info("");

			sleep(10);
			String slow="s";
			for (int calc = 1; calc <= 2000; calc++)
			{
				slow=slow +"s";
			}				
			final Sigar sigar = new Sigar();
			final long[] processes;
			try
			{
				processes = sigar.getProcList();
			} catch (Exception e)
			{
				throw new ErrorException("can't access pids list", 1);
			}

			for (final long processId : processes)
			{
				try
				{
					ProcCpu procCpu = sigar.getProcCpu(processId);
					String name = ProcUtil.getDescription(sigar, processId);
					if (procCpu.getPercent() > 0.001f)
					{
						maxCpu = procCpu.getPercent();
						logger.info(processId+ "\t 0001 set max " + name + "\t" + procCpu.getPercent()+ "\t cpu " + cpu+ "\t maxCpu " + maxCpu);
						if (processId==accrobatPID)
						{
							cpu = procCpu.getPercent()+ 0.000f;
							logger.info(processId+ "\t set cpu " + name + " is acrobat\t" + procCpu.getPercent()+ "\t cpu " + cpu+ "\t maxCpu " + maxCpu);
						}
						//if (procCpu.getPercent() > 0.5f)
						//{
						//	if (name.toLowerCase().contains("javaw"))
						//	{
						//		cpu = procCpu.getPercent()+ 0.000f;
						//		logger.info(processId+ "\t set cpu " + name + " is javaw\t" + procCpu.getPercent()+ "\t cpu " + cpu+ "\t maxCpu " + maxCpu);
						//	}
						//}
					}
				} catch (SigarException e)
				{
					// for denied access on some pid
				}

			}

			// check about infinite loop
			watchDog++;
			if (watchDog == 100)
			{
				throw new ErrorException("infinite loop, procCpu values always 0", 1);
			}

			if (maxCpu == 0.0f)
			{
				logger.info(" ----->nothing found during getProcCpu reading. Already tried: \t" + "\t" + watchDog);
			} else
			{
				logger.info(" ----->found this cpu for accrobat or explore \t" + "\t" + cpu);
			}

		} while (maxCpu == 0.0f);
		return cpu;
	}


	public void sleep(Integer delay) throws ErrorException
	{
		try
		{
			Thread.sleep(delay);
		}
		catch (InterruptedException e)
		{
			throw new ErrorException("77 : " + e.getMessage(), 1);
		}
	}
	
	/**
	 * return the percentage of CPU usage
	 * 
	 * @param page
	 *            used in logs
	 * @return the percentage of CPU usage
	 */
	public int getAcrobatPID() throws ErrorException
	{

		int accrobatPID=0;
        Kernel32 kernel32 = (Kernel32) Native.loadLibrary(Kernel32.class, W32APIOptions.UNICODE_OPTIONS);
        Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference();          

        WinNT.HANDLE snapshot = kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0));
        try  {
            while (kernel32.Process32Next(snapshot, processEntry)) {             
                //System.out.println(processEntry.th32ProcessID + "\t" + Native.toString(processEntry.szExeFile)+ "\t");
                if (Native.toString(processEntry.szExeFile).toLowerCase().contains("acrobat"))         {
                	accrobatPID=processEntry.th32ProcessID.intValue();
                }
            }
        }
        finally {
            kernel32.CloseHandle(snapshot);
        }

        
		return accrobatPID;
	}

}
