package org.kne.cloud.network.klalb;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.function.Consumer;

import org.kne.cloud.network.KLALBDetectorItem;
import org.kne.cloud.network.MultiProtocolSocketAddress;
import org.kne.cloud.network.ProtocolDetector;
import org.kne.cloud.network.ProtocolDetectorServerSocket;
import org.kne.cloud.network.ProtocolDetectorSocket;
import org.kne.cloud.network.SocketListener;

public class KLALBProtocolDetectSocketListener extends SocketListener {

	private volatile Consumer<Socket> conx;
	private KLALBController klalbController;

	@Override
	protected void open() throws UnknownHostException, IOException {
		if(serverSocket==null)
			serverSocket=getMultipurposeSocketAddress().listenServerSocket();
		if(!(serverSocket instanceof ProtocolDetectorServerSocket)) {
			ProtocolDetector pd=new ProtocolDetector();
			pd.add(new KLALBDetectorItem());
			serverSocket=new ProtocolDetectorServerSocket(serverSocket,pd);
		}
		super.open();
	}

	public KLALBProtocolDetectSocketListener(MultiProtocolSocketAddress multiProtocolSocketAddress, KLALBController klalbc) throws IOException {
		super(multiProtocolSocketAddress);
		this.klalbController=klalbc;
	}

	public KLALBProtocolDetectSocketListener(ServerSocket tserverSocket,KLALBController klalbc) throws IOException {
		super(tserverSocket);
		this.klalbController=klalbc;
	}
	{

		super.setCon((soc)->{
			ProtocolDetectorSocket pds=(ProtocolDetectorSocket) soc;
			if(!pds.getProtocolStack().isEmpty()&&pds.getProtocolStack().pop().getName().equals("KLALB")) {
				KLALBRemoteLink krs=null;
				try {
					krs = new KLALBRemoteLink(klalbController,new StreamKLALBPacketLink(pds));
					klalbController.addRemoteLine(krs);
				} catch (Exception e) {
					e.printStackTrace();
					try {
						soc.close();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
					
				}
				}else {
					if(conx!=null) {
						try {
					conx.accept(soc);
					} catch (Exception e) {
						e.printStackTrace();
						try {
							soc.close();
						} catch (IOException e1) {
							e1.printStackTrace();
						}
						
					}
					}else {
						try {
							soc.close();
						} catch (IOException e1) {
							e1.printStackTrace();
						}
					}
				}
		});
	}
	@Override
	public Consumer<Socket> getCon() {
		return conx;
	}

	@Override
	public void setCon(Consumer<Socket> conx) {
		this.conx=conx;
	}

	public KLALBController getKlalbController() {
		return klalbController;
	}

}
