package org.kne.cloud.network.klalb;

import java.io.IOException;
import java.util.LinkedHashMap;

import org.kne.cloud.network.DefaultMinecraftSocketBridgeFactory;
import org.kne.cloud.network.DefaultSocketBridgeFactory;
import org.kne.cloud.network.HostPortMap;
import org.kne.cloud.network.MultiProtocolSocketAddress;
import org.kne.cloud.network.Proxy;
import org.kne.cloud.network.SocketBridgeFactory;
import org.kne.cloud.network.SocketToSocketProxy;

public class SocketBridgeConfigItem extends KLALBConfigItem {
	private MultiProtocolSocketAddress Listen;
	
	private LinkedHashMap<String, String>Bridge=new LinkedHashMap<>();
	private HostPortMap Connect=new HostPortMap();
	
	public SocketBridgeConfigItem( MultiProtocolSocketAddress listen,
			LinkedHashMap<String, String> bridge, HostPortMap connect) {
		super("SocketBridge");
		Listen = listen;
		Bridge = bridge;
		Connect = connect;
	}
	
	
	@Override
	public String toString() {
		return "SocketBridgeConfigItem [Listen=" + Listen + ", Bridge=" + Bridge + ", Connect=" + Connect + "]";
	}


	/*public static JsonDeserializer<SocketBridgeConfigItem> getSocketBridgeConfigItemJsonDeserializer(){
		return new JsonDeserializer<SocketBridgeConfigItem>() {
			
			@Override
			public SocketBridgeConfigItem deserialize(JsonElement arg0, Type arg1, JsonDeserializationContext arg2)
					throws JsonParseException {
				if(arg0.isJsonObject()) {
				HostPortMap mapp=new HostPortMap();
				LinkedHashMap<String, SocketBridgeFactory>mapb=new LinkedHashMap<>();
				MultipurposeSocketAddress l=new MultipurposeSocketAddress(((JsonObject) arg0).get("Listen").getAsString());
				SocketBridgeFactory bdg=getDefaultBridgeFactory(((JsonObject)arg0).get("Bridge"),mapb);
				MultipurposeSocketAddress r=getDefaultConnect(((JsonObject)arg0).get("Connect"),mapp);
				return new SocketBridgeConfigItem(l,mapb,mapp);
				}else {
					throw new JsonParseException("not a object:"+arg0);
				}
			}
		};
	}
	public static JsonSerializer<SocketBridgeConfigItem> getSocketBridgeConfigItemJsonSerializer(){
		return new JsonSerializer<SocketBridgeConfigItem>() {
			
			@Override
			public JsonElement serialize(SocketBridgeConfigItem arg0, Type arg1, JsonSerializationContext arg2) {
				return null;
				
			}
		};
	}
	public static void registerToGsonBuilder(GsonBuilder gsonBuilder) {
		gsonBuilder.registerTypeAdapter(SocketBridgeConfigItem.class, getSocketBridgeConfigItemJsonDeserializer());
		gsonBuilder.registerTypeAdapter(SocketBridgeConfigItem.class, getSocketBridgeConfigItemJsonSerializer());
	}*/
	public Proxy createProxy(KLALBController controller) throws IOException {
		HostPortMap mapp=new HostPortMap();
		LinkedHashMap<String, SocketBridgeFactory>mapb=new LinkedHashMap<>();
		MultiProtocolSocketAddress l=Listen;
		SocketBridgeFactory bdg=getDefaultBridgeFactory(Bridge,mapb,controller);
		MultiProtocolSocketAddress r=getDefaultConnect(Connect,mapp);
		return new SocketToSocketProxy(l ,new MultiProtocolSocketAddress("0.0.0.0:0"), r,mapp,bdg,mapb);
	}
	private MultiProtocolSocketAddress getDefaultConnect(HostPortMap connect2, LinkedHashMap<String, MultiProtocolSocketAddress> mapp) {
			connect2.entrySet().forEach((en)->{
				mapp.put(en.getKey(),  en.getValue());
			});
			return mapp.get("DEFAULT");
	}
	private SocketBridgeFactory getDefaultBridgeFactory(LinkedHashMap<String, String> bridge2, LinkedHashMap<String, SocketBridgeFactory> mapp, KLALBController controller) {
		bridge2.entrySet().forEach((en)->{
				mapp.put(en.getKey(), getFactoryByJobj(en.getValue(), controller));
			});
			return mapp.get("DEFAULT");
	}private SocketBridgeFactory getFactoryByJobj(String string,KLALBController controller) {
		if(string.startsWith("SocketBridge")) {
			return new DefaultSocketBridgeFactory();
		}else if(string.startsWith("MinecraftSocketBridge")) {
			return new DefaultMinecraftSocketBridgeFactory(controller.getSelf().getAddress().toInet6Address(), Integer.parseInt(string.substring(21)));
		}
		throw new IllegalArgumentException("unknown SocketBridge type:"+string);
	}
}
