package org.bench4q.monitor.files;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.bench4q.monitor.entiry.MonitorContorlEntity;
import org.bench4q.monitor.file.Linux.WriteLogicalDiskLinux;
import org.bench4q.monitor.file.Linux.WriteMemoryLinux;
import org.bench4q.monitor.file.Linux.WriteNetworkInterfaceLinux;
import org.bench4q.monitor.file.Linux.WritePhysicalDiskLinux;
import org.bench4q.monitor.file.Linux.WriteProcessLinux;
import org.bench4q.monitor.file.Linux.WriteProcessorLinux;
import org.bench4q.monitor.file.Linux.WriteSystemLinux;
import org.bench4q.monitor.file.windows.WriteLogicalDiskWindows;
import org.bench4q.monitor.file.windows.WriteMemoryWindows;
import org.bench4q.monitor.file.windows.WriteNetworkInterfaceWindows;
import org.bench4q.monitor.file.windows.WritePhysicalDiskWindows;
import org.bench4q.monitor.file.windows.WriteProcessWindows;
import org.bench4q.monitor.file.windows.WriteProcessorWindows;
import org.bench4q.monitor.file.windows.WriteSystemWindows;

public class WriteFiles extends MonitorContorlEntity {
	public static boolean flag = true;
	private int threadCount;
	private int saveCount;
	private ExecutorService service;
	WriteLogicalDiskWindows logicalDiskWindows;
	WriteMemoryWindows memoryWindows;
	WriteNetworkInterfaceWindows networkInterfaceWindows;
	WritePhysicalDiskWindows physicalDiskWindows;
	WriteProcessorWindows processorWindows;
	WriteSystemWindows systemWindows;
	WriteProcessWindows processWindows;

	WriteLogicalDiskLinux logicalDiskLinux;
	WriteMemoryLinux memoryLinux;
	WriteNetworkInterfaceLinux networkInterfaceLinux;
	WritePhysicalDiskLinux physicalDiskLinux;
	WriteProcessorLinux processorLinux;
	WriteSystemLinux systemLinux;
	WriteProcessLinux processLinux;

	public WriteFiles() throws FileNotFoundException {
		this.threadCount = 7;
		this.saveCount = 150;
		service = null;
		PrintWriter out = null;
		if (this.getOsNameString().contains("windows")) {

			logicalDiskWindows = new WriteLogicalDiskWindows(out,
					this.getIdleTime());
			memoryWindows = new WriteMemoryWindows(out, this.getIdleTime());
			networkInterfaceWindows = new WriteNetworkInterfaceWindows(out,
					this.getIdleTime());
			physicalDiskWindows = new WritePhysicalDiskWindows(out,
					this.getIdleTime());
			processorWindows = new WriteProcessorWindows(out,
					this.getIdleTime());
			systemWindows = new WriteSystemWindows(out, this.getIdleTime());
			processWindows = new WriteProcessWindows(out, this.getIdleTime());

		} else {
			logicalDiskLinux = new WriteLogicalDiskLinux(out,
					this.getIdleTime());
			memoryLinux = new WriteMemoryLinux(out, this.getIdleTime());
			networkInterfaceLinux = new WriteNetworkInterfaceLinux(out,
					this.getIdleTime());
			physicalDiskLinux = new WritePhysicalDiskLinux(out,
					this.getIdleTime());
			processorLinux = new WriteProcessorLinux(out, this.getIdleTime());
			systemLinux = new WriteSystemLinux(out, this.getIdleTime());
			processLinux = new WriteProcessLinux(out, this.getIdleTime());

		}

	}

	public void start() throws FileNotFoundException {

		Executors.newFixedThreadPool(threadCount);
		int time_count = 0;
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHH:mm:ss");
		String filePath;
		PrintWriter netPt = null, logicalPt = null, /* processPt = null, */processorPt = null, physicalPt = null, memoryPt = null, systemPt = null;

		if (this.getOsNameString().contains("windows")) {
			while (flag) {

				if ((time_count % saveCount) == 0) {
					time_count = 0;
					df.format(new Date());
					filePath = new CreatFileName("NetworkInterface",
							df.toString()).getFileName();
					netPt = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(new FileOutputStream(
									new File(filePath)))));
					networkInterfaceWindows.setOut(netPt);

					filePath = new CreatFileName("LogicalDisk", df.toString())
							.getFileName();
					logicalPt = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(new FileOutputStream(
									new File(filePath)))));
					logicalDiskWindows.setOut(logicalPt);

					filePath = new CreatFileName("Process", df.toString())
							.getFileName();
					// processPt = new PrintWriter(new BufferedWriter(
					// new OutputStreamWriter(new FileOutputStream(
					// new File(filePath)))));
					physicalDiskWindows.setOut(physicalPt);

					filePath = new CreatFileName("Processor", df.toString())
							.getFileName();
					processorPt = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(new FileOutputStream(
									new File(filePath)))));
					processorWindows.setOut(processorPt);

					filePath = new CreatFileName("PhysicalDisk", df.toString())
							.getFileName();
					physicalPt = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(new FileOutputStream(
									new File(filePath)))));
					physicalDiskWindows.setOut(physicalPt);

					filePath = new CreatFileName("Memory", df.toString())
							.getFileName();
					memoryPt = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(new FileOutputStream(
									new File(filePath)))));
					memoryWindows.setOut(memoryPt);

					filePath = new CreatFileName("System", df.toString())
							.getFileName();
					systemPt = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(new FileOutputStream(
									new File(filePath)))));
					systemWindows.setOut(systemPt);
				}
				service.execute(systemWindows);
				service.execute(physicalDiskWindows);
				service.execute(processorLinux);
				service.execute(memoryWindows);
				service.execute(logicalDiskWindows);
				service.execute(processWindows);
				service.execute(networkInterfaceWindows);
				time_count++;
			}

		} else {
			while (flag) {

				if ((time_count % saveCount) == 0) {
					time_count = 0;
					df.format(new Date());
					filePath = new CreatFileName("NetworkInterface",
							df.toString()).getFileName();
					netPt = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(new FileOutputStream(
									new File(filePath)))));
					networkInterfaceLinux.setOut(netPt);

					filePath = new CreatFileName("LogicalDisk", df.toString())
							.getFileName();
					logicalPt = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(new FileOutputStream(
									new File(filePath)))));
					logicalDiskLinux.setOut(logicalPt);

					filePath = new CreatFileName("Process", df.toString())
							.getFileName();
					// processPt = new PrintWriter(new BufferedWriter(
					// new OutputStreamWriter(new FileOutputStream(
					// new File(filePath)))));
					physicalDiskLinux.setOut(physicalPt);

					filePath = new CreatFileName("Processor", df.toString())
							.getFileName();
					processorPt = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(new FileOutputStream(
									new File(filePath)))));
					processorLinux.setOut(processorPt);

					filePath = new CreatFileName("PhysicalDisk", df.toString())
							.getFileName();
					physicalPt = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(new FileOutputStream(
									new File(filePath)))));
					physicalDiskLinux.setOut(physicalPt);

					filePath = new CreatFileName("Memory", df.toString())
							.getFileName();
					memoryPt = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(new FileOutputStream(
									new File(filePath)))));
					memoryLinux.setOut(memoryPt);

					filePath = new CreatFileName("System", df.toString())
							.getFileName();
					systemPt = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(new FileOutputStream(
									new File(filePath)))));
					systemLinux.setOut(systemPt);
				}
				service.execute(systemLinux);
				service.execute(physicalDiskLinux);
				service.execute(processorLinux);
				service.execute(memoryLinux);
				service.execute(logicalDiskLinux);
				service.execute(processLinux);
				service.execute(networkInterfaceLinux);
				time_count++;
			}

		}

	}

	public void stop() throws InterruptedException {
		flag = false;
		service.shutdown();
		service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
		flag = false;

	}

}
