package org.kne.cloud.network.minecraft;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.Scanner;

import org.kne.cloud.network.MultipurposeSocketAddress;
import org.kne.cloud.network.ProtocolDetectorServerSocketFactory;
import org.kne.cloud.network.ProtocolDetectorSocket;
import org.kne.cloud.network.SocketListener;
import org.kne.cloud.network.SocketType;
import org.kne.cloud.network.klalb.CONST;
import org.kne.cloud.network.klalb.KLALBController;
import org.kne.cloud.network.klalb.KLALBRemoteLine;
import org.kne.cloud.network.klalb.KLALBVirtualSocket;
import org.kne.cloud.network.klalb.ServerPropties;
import org.kne.cloud.network.klalb.StreamKLALBPacketLink;

public class SimpleKLALBMinecraftServer {
	public static SocketListener tcpl,tcpl2;
	public static ServerPropties sp;
	public static KLALBController kc;
	static {
		MultipurposeSocketAddress.getSocketTypeRegister().put("DETTCP",new SocketType(null, new ProtocolDetectorServerSocketFactory()));
	}
	public static void main(String[] args) throws IOException {

		System.out.println(CONST.klalb+"[Minecraft版] V"+CONST.klalbver);
		sp=new ServerPropties();
		
		System.out.println("虚拟地址："+sp.getVirtualIP().getHostAddress());
		kc=new KLALBController(sp.getVirtualIP());
		kc.setSelflineTableSupplier(()->{
			return fileRead("linetable.txt");
		});
		kc.registerToProxyTypeAs("KLALB");
	
		System.out.println("开放端口："+sp.getBind());
		openPort(sp.getBind());
		System.out.println("本地服务："+sp.getLocal());
		openLocalPort(sp.getLocal());
		
	
		
		Scanner scn=new Scanner(System.in);
		while(true) {
		String s=scn.next();
		String[]sc=s.split(" ");
		switch(sc[0]) {
		case "help":
			System.out.print("state:查看线路状态");
			System.out.println("reload:重新加载线路配置");
		break;
		case "state":
			System.out.println("状态\t上传流量\t下载流量\t上传速度\t下载速度\t延迟\t抖动\t下一次重试");
			for (Iterator<KLALBRemoteLine> iterator = kc.getLines().iterator(); iterator.hasNext();) {
				KLALBRemoteLine hostPort =  iterator.next();
				System.out.println(hostPort .toString2());
				//System.out.println();
			}
			break;
		default:
			System.out.println("未知命令，请输入help以查询指令说明");
		}
		}
	}
	private static void openPort(String bip) throws IOException {
		if(tcpl!=null)
			tcpl.close();
		MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(bip,"DETTCP");
		tcpl=new SocketListener(mpsa);
		tcpl.setCon((soc)->{
			ProtocolDetectorSocket pds=(ProtocolDetectorSocket) soc;
		if(!pds.getProtocolStack().isEmpty()&&pds.getProtocolStack().pop().getName().equals("KLALB")) {
			KLALBRemoteLine krs=null;
			try {
				krs = new KLALBRemoteLine(new StreamKLALBPacketLink(pds));
			kc.addRemoteLine(krs);
			} catch (IOException e) {
				e.printStackTrace();
			}
			}else {
				MultipurposeSocketAddress mpsa2=new MultipurposeSocketAddress(sp.getLocal());
				Socket s=null;
				try {
					s=mpsa2.connectSocket();
					MinecraftSocketBridge dsb=new MinecraftSocketBridge(pds, s);
					dsb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return kc.getSelf();},()->{return 23333;}));
					dsb.run();
				} catch (UnknownHostException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				} catch (IOException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}finally {
					if(s!=null)
						try {
							s.close();
						} catch (IOException e1) {
							// TODO 自动生成的 catch 块
							e1.printStackTrace();
						}
					try {
						soc.close();
					} catch (IOException e) {
						// TODO 自动生成的 catch 块
						e.printStackTrace();
					}
				}
			}
		});
	}
	private static void openLocalPort(String bip) throws IOException {
		if(tcpl2!=null)
			tcpl2.close();
		MultipurposeSocketAddress mpsa=new MultipurposeSocketAddress(bip);
		tcpl2=new SocketListener(new MultipurposeSocketAddress("KLALB_Stream", "::0", 23333));
		tcpl2.setCon((soc)->{
			Socket s=null;
			try {
				s=mpsa.connectSocket();
				s.setTcpNoDelay(true);
				//soc.setTcpNoDelay(true);
				//((KLALBVirtualSocket) soc).setCompress(1);
				MinecraftSocketBridge dsb=new MinecraftSocketBridge(soc, s);
				dsb.getBridgeBA().getTransformers().add(new KLALBJsonMotdInserter(()->{return kc.getSelf();},()->{return 23333;}));
				//dsb.getSab().setDelay(1);
				dsb.run();
				/*CompressedSocketBridge csb=new CompressedSocketBridge(s, soc);
				csb.getSab().setDelay(1);
				csb.run();*/
			} catch (UnknownHostException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}finally {
				if(s!=null)
					try {
						s.close();
					} catch (IOException e1) {
						// TODO 自动生成的 catch 块
						e1.printStackTrace();
					}
				try {
					soc.close();
				} catch (IOException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}
			}
			
		});
	}
	  private static String fileRead(String filePath){
	        //1.定义一个BufferedReader对象，将文件内容读取到缓存
	        BufferedReader bufferedReader =null;
	        String returnInfo="";
	        try{
	            // 2.定义一个file对象
	            File file = new File(filePath);//定义一个file对象，用来初始化FileReader
	            // 3.定义一个fileReader对象
	            FileReader reader = new FileReader(file);
	            // 4.定义一个BufferedReader对象，将文件内容读取到缓存
	            bufferedReader = new BufferedReader(reader);
	            // 5.定义一个字符串缓存，将字符串存放缓存中
	            StringBuilder stringBuilder = new StringBuilder();
	            String str = "";
	            while ((str =bufferedReader.readLine()) != null) {//逐行读取文件内容，不读取换行符和末尾的空格
	                stringBuilder.append(str + "\n");//将读取的字符串添加换行符后累加存放在缓存中
	            }
	            returnInfo = stringBuilder.toString();
	        }catch (Exception e){
	           e.printStackTrace();
	        }finally {
	            try{
	                if(bufferedReader!=null){
	                    bufferedReader.close();
	                }
	            }catch (Exception e){
	              e.printStackTrace();
	            }
	        }
	        return returnInfo;
	    }

}
