package org.kne.cloud.network.klalb;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.List;

import org.kne.cloud.network.MultiProtocolSocketAddress;
import org.kne.cloud.network.SocketListener;
import org.kne.cloud.network.ipv6.IPv6NetworkLink;
import org.kne.cloud.network.monitor.LinkStatus;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;

public class KLALBRemoteManagement {
	SocketListener slr;
	private KLALBProxySystem klalbProxySystem;
	public KLALBRemoteManagement(KLALBProxySystem klalbProxySystem) throws IOException {
		this(klalbProxySystem,new MultiProtocolSocketAddress("127.9.9.9", 49573));
	}
	public KLALBRemoteManagement(KLALBProxySystem klalbProxySystem, MultiProtocolSocketAddress listen) throws IOException {
		this.klalbProxySystem=klalbProxySystem;
		slr=new SocketListener(listen);
		slr.setCon((srcv)->{
			try {
				srcv.setSoTimeout(10000);
				byte[]input= srcv.getInputStream().readAllBytes();
				srcv.shutdownInput();
				String req=new String(input,Charset.forName("UTF-8"));
				System.out.println("远程管理请求："+req);
				String rsp=processSignal(req);
				System.out.println("远程管理响应："+rsp);
				srcv.getOutputStream().write(rsp.getBytes(Charset.forName("UTF-8")));
				srcv.shutdownOutput();
			} catch (IOException e) {
				e.printStackTrace();
			}finally {
				try {
					srcv.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
		});
	}
	public KLALBProxySystem getKlalbProxySystem() {
		return klalbProxySystem;
	}
	private String processSignal(String req) {
		JsonObject jreq= (JsonObject) new JsonParser().parse(req);
		JsonObject jrsp=new JsonObject();
		
		
		String reqt=jreq.getAsJsonPrimitive("REQ").getAsString();
		jrsp.addProperty("RSP", reqt);
		switch (reqt) {
		case "GETLINES":
			JsonArray lines=new JsonArray();
			List<IPv6NetworkLink>lineslist= klalbProxySystem.getKlalbController().getLines();
			synchronized (lineslist) {
				for (Iterator<IPv6NetworkLink> iterator = lineslist.iterator(); iterator.hasNext();) {
					IPv6NetworkLink link=iterator.next();
					if(!(link instanceof KLALBRemoteLink)) {
						continue;
					}
					KLALBRemoteLink klalbRemoteLine = (KLALBRemoteLink) link;
					if(klalbRemoteLine.getSocketAddress()==null)
						continue;
					JsonObject jklbrl=new JsonObject();
					jklbrl.addProperty("ipport", klalbRemoteLine.getSocketAddress().toString());
					jklbrl.addProperty("state",LinkStatus.stateToString( klalbRemoteLine.getState()));
					
					jklbrl.addProperty("Vaddr", klalbRemoteLine.getRemoteVaddr().getAddress().toString());
					
					jklbrl.addProperty("uploadspeed", klalbRemoteLine.getMonitor().getOutSpeed());
					jklbrl.addProperty("downloadspeed", klalbRemoteLine.getMonitor().getInSpeed());
					
					jklbrl.addProperty("uploadtraffic", klalbRemoteLine.getMonitor().getOutTraffic());
					jklbrl.addProperty("downloadtraffic",  klalbRemoteLine.getMonitor().getInTraffic());
					
					jklbrl.addProperty("uploaddelay",klalbRemoteLine.getMonitor().getOutDelay() );
					jklbrl.addProperty("downloaddelay", klalbRemoteLine.getMonitor().getInDelay());
					
					jklbrl.addProperty("uploaddelaymin",klalbRemoteLine.getMonitor().getOutDelayMin() );
					jklbrl.addProperty("downloaddelaymin", klalbRemoteLine.getMonitor().getInDelayMin());
					lines.add(jklbrl);
				}
			}
			jrsp.add("table", lines);
			break;
		case "ADDLINE":
			String mip=jreq.getAsJsonPrimitive("ipport").getAsString();
			try {
				
			jrsp.addProperty ("Vaddr",klalbProxySystem.getKlalbController().getRemoteVaddrBySocketAddress(new MultiProtocolSocketAddress(mip)).getHostAddress());
			} catch (SocketTimeoutException e) {
				e.printStackTrace();
			}
			break;
		case "GETSELFLINES":	
			JsonArray lines2=new JsonArray();
			List<MultiProtocolSocketAddress>selflineslist=klalbProxySystem.getKlalbController().getSelflineTable();
			synchronized (selflineslist) {
				for (Iterator<MultiProtocolSocketAddress> iterator = selflineslist.iterator(); iterator.hasNext();) {
					MultiProtocolSocketAddress multiProtocolSocketAddress = (MultiProtocolSocketAddress) iterator.next();
					lines2.add(new JsonPrimitive(multiProtocolSocketAddress.toString()));
				}
			}
			jrsp.add("table", lines2);
			
			break;
		case "ADDSELFLINE":
			String mips=jreq.getAsJsonPrimitive("ipport").getAsString();
			List<MultiProtocolSocketAddress>selflineslist2=klalbProxySystem.getKlalbController().getSelflineTable();
			synchronized (selflineslist2) {
				selflineslist2.add(new MultiProtocolSocketAddress(mips));
			}
			break;
		case "REMOVESELFLINE":
			String mipsr=jreq.getAsJsonPrimitive("ipport").getAsString();
			List<MultiProtocolSocketAddress>selflineslist21=klalbProxySystem.getKlalbController().getSelflineTable();
			synchronized (selflineslist21) {
				selflineslist21.add(new MultiProtocolSocketAddress(mipsr));
			}
			break;
		case "GETLINKMONITOR":
			jrsp.addProperty("uploadspeed", klalbProxySystem.getKlalbController().getLinkMonitor().getOutSpeed());
			jrsp.addProperty("downloadspeed", klalbProxySystem.getKlalbController().getLinkMonitor().getInSpeed());
			
			jrsp.addProperty("uploadtraffic", klalbProxySystem.getKlalbController().getLinkMonitor().getOutTraffic());
			jrsp.addProperty("downloadtraffic",  klalbProxySystem.getKlalbController().getLinkMonitor().getInTraffic());
			
			break;
		case "OPENMONITORUI":
			klalbProxySystem.getKLALBGUI().setVisible(true);
			break;
		/*case "GETSOCKETBRIDGE":
			JsonArray bridges=new JsonArray();
			Set<Proxy> pxy=klalbProxySystem.getProxys();
			synchronized (pxy) {
				for (Iterator<Proxy> iterator = pxy.iterator(); iterator.hasNext();) {
					Proxy proxy = (Proxy) iterator.next();
					bridges.add(klalbProxySystem.createJsonObjectByProxy(proxy));
				}
			}
			jrsp.add("table", bridges);
			break;
		case "ADDSOCKETBRIDGE":
			JsonObject jpxy= jreq.getAsJsonObject("socketbridge");
			Set<Proxy> pxy2=klalbProxySystem.getProxys();
			synchronized (pxy2) {
				try {
					pxy2.add(klalbProxySystem.createProxyByJson(jpxy));
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			break;*/
		default:
			System.out.println("未知请求类型："+reqt);
			break;
		}
		
		return jrsp.toString();
	}
	public void close() {
		slr.close();
	}
}
