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.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.bench4q.monitor.entiry.LinuxFileRead;
import org.bench4q.monitor.model.NetworkInterfaceModel;
import org.bench4q.monitor.model.NetworkInterfaceModelChild;

public class NetworkInterfaceMonitor extends LinuxFileRead {
	// /proc/net/dev
	public NetworkInterfaceMonitor() throws FileNotFoundException {
		super("/proc/net/dev");
		bytesTotalPerSecond = new HashMap<String, Double>();
		bytesReceivedPerSecond = new HashMap<String, Double>();
		bytesSentPerSecond = new HashMap<String, Double>();
		instances = new ArrayList<String>();
	}

	private Map<String, Double> bytesTotalPerSecond;
	private Map<String, Double> bytesReceivedPerSecond;
	private Map<String, Double> bytesSentPerSecond;
	private List<String> instances;

	public List<String> getInstances() throws IOException, InterruptedException {
		getNetworkInterfaceInfo(1000);
		return instances;
	}

	public double getBytesTotalPerSecond(String instance, int idleTime)
			throws IOException, InterruptedException {
		getNetworkInterfaceInfo(idleTime);
		return bytesTotalPerSecond.get(instance);
	}

	public double getBytesReceivedPerSecond(String instance, int idleTime)
			throws IOException, InterruptedException {
		getNetworkInterfaceInfo(idleTime);
		return bytesReceivedPerSecond.get(instance);
	}

	public double getBytesSentPerSecond(String instacne, int idleTime)
			throws IOException, InterruptedException {
		getNetworkInterfaceInfo(idleTime);
		return bytesSentPerSecond.get(instacne);
	}

	public NetworkInterfaceModel getNetworkInterfaceInfo(int idleTime)
			throws IOException, InterruptedException {
		NetworkInterfaceModel networkInterfaceModel = new NetworkInterfaceModel();
		int time = idleTime / 1000;
		BufferedReader br = this.getBufferedReader();
		Map<String, Double> bytesReceived = new HashMap<String, Double>();
		Map<String, Double> bytesSent = new HashMap<String, Double>();
		String nextline;
		br.readLine();
		br.readLine();
		StringTokenizer token;
		while ((nextline = br.readLine()) != null) {
			if (nextline.contains("eth")) {
				token = new StringTokenizer(nextline);
				String instance = token.nextToken().replace(":", "");// instance
				instances.add(instance);
				String str = token.nextToken();// received bytes
				bytesReceived.put(instance, Double.parseDouble(str));
				for (int i = 0; i < 7; i++)
					token.nextToken();
				str = token.nextToken();
				bytesSent.put(instance, Double.parseDouble(str));
			}
		}
		Thread.sleep(idleTime);
		br = new BufferedReader(new InputStreamReader(new FileInputStream(
				new File("/proc/net/dev"))));
		br.readLine();
		br.readLine();
		while ((nextline = br.readLine()) != null) {
			if (nextline.contains("eth")) {
				token = new StringTokenizer(nextline);
				String instance = token.nextToken().replace(":", "");// instance
				String str = token.nextToken();// received bytes

				bytesReceived.put(instance, Double.parseDouble(str)
						- bytesReceived.get(instance));
				for (int i = 0; i < 7; i++)
					token.nextToken();
				str = token.nextToken();

				bytesSent.put(instance,
						Double.parseDouble(str) - bytesReceived.get(instance));
				bytesReceivedPerSecond.put(instance,
						bytesReceived.get(instance) / time);
				bytesSentPerSecond
						.put(instance, bytesSent.get(instance) / time);
				bytesTotalPerSecond.put(instance,
						bytesReceivedPerSecond.get(instance)
								+ bytesSentPerSecond.get(instance));
			}
		}
		Iterator<String> itr = instances.iterator();
		while (itr.hasNext()) {
			String instance = itr.next();
			NetworkInterfaceModelChild networkInterfaceModelChild = new NetworkInterfaceModelChild();
			networkInterfaceModelChild
					.setBytesReceivedPerSecond(bytesReceivedPerSecond
							.get(instance));
			networkInterfaceModelChild.setBytesSentPerSecond(bytesSentPerSecond
					.get(instance));
			networkInterfaceModelChild
					.setBytesTotalPerSecond(bytesTotalPerSecond.get(instance));
			networkInterfaceModelChild.setInstance(instance);
			networkInterfaceModel.getNetworkList().add(
					networkInterfaceModelChild);
		}
		br.close();
		return networkInterfaceModel;
	}

}
