package org.bench4q.monitor.performance.linux;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.bench4q.monitor.entiry.LinuxFileRead;
import org.bench4q.monitor.model.ProcessorModel;
import org.bench4q.monitor.model.ProcessorModelChild;
import org.bench4q.monitor.model.SystemModel;

public class SystemMonitor extends LinuxFileRead {

	public SystemMonitor() throws FileNotFoundException {
		super("/proc/stat");

	}

	public double getTotalProceesorTimePercent(int idleTime)
			throws IOException, InterruptedException {
		getSystemInfo(idleTime);
		return totalProceesorTimePercent;
	}

	public double getProcessorQueueLength() throws IOException,
			InterruptedException {
		getSystemInfo(1000);
		return processorQueueLength;
	}

	public double getFileDataOperationsPerSecond(int idleTime)
			throws IOException, InterruptedException {
		getSystemInfo(idleTime);
		return fileDataOperationsPerSecond;
	}

	private double totalProceesorTimePercent;
	private double processorQueueLength;
	private double fileDataOperationsPerSecond;

	public SystemModel getSystemInfo(int idleTime) throws IOException,
			InterruptedException {
		SystemModel systemModel = new SystemModel();
		totalProceesorTimePercent = 0;
		fileDataOperationsPerSecond = 0;
		String nextline;
		StringTokenizer token = null;
		ProcessorMonitor pm = new ProcessorMonitor();
		// "in" is used for reading file "proc/diskstats"
		BufferedReader in = new BufferedReader(new InputStreamReader(
				new FileInputStream(new File("/proc/diskstats"))));
		while ((nextline = in.readLine()) != null) {
			if (nextline.contains("8       0 ")) {
				token = new StringTokenizer(nextline);
				token.nextToken();
				token.nextToken();
				token.nextToken();
				fileDataOperationsPerSecond -= Integer.parseInt(token
						.nextToken());
				token.nextToken();
				token.nextToken();
				token.nextToken();
				fileDataOperationsPerSecond -= Integer.parseInt(token
						.nextToken());
			}
		}
		in.close();
		ProcessorModel pModel = pm.getProcessorInfo(idleTime);
		BufferedReader br = this.getBufferedReader();

		while ((nextline = br.readLine()) != null) {
			if (nextline.contains("procs_running")) {
				token = new StringTokenizer(nextline);
				token.nextToken();
				processorQueueLength += Integer.parseInt(token.nextToken());
			}
			if (nextline.contains("procs_blocked")) {
				token = new StringTokenizer(nextline);
				token.nextToken();
				processorQueueLength += Integer.parseInt(token.nextToken());
			}

		}
		br.close();
		in = new BufferedReader(new InputStreamReader(new FileInputStream(
				new File("/proc/diskstats"))));
		while ((nextline = in.readLine()) != null) {
			if (nextline.contains("8       0 ")) {
				token = new StringTokenizer(nextline);
				token.nextToken();
				token.nextToken();
				token.nextToken();
				fileDataOperationsPerSecond += Integer.parseInt(token
						.nextToken());
				token.nextToken();
				token.nextToken();
				token.nextToken();
				fileDataOperationsPerSecond += Integer.parseInt(token
						.nextToken());
			}
		}
		in.close();
		fileDataOperationsPerSecond = fileDataOperationsPerSecond
				/ (idleTime / 1000);

		List<ProcessorModelChild> list = pModel.getProcessorModelList();
		Iterator<ProcessorModelChild> itr = list.iterator();
		while (itr.hasNext()) {
			totalProceesorTimePercent += itr.next().getProcessorTimePercent();
		}
		systemModel.setFileDataOperationsPerSecond(fileDataOperationsPerSecond);
		systemModel.setProcessorQueueLength(processorQueueLength);
		systemModel.setTotalProceesorTimePercent(totalProceesorTimePercent);
		return systemModel;

	}

}
