package org.kne.cloud.network;

import java.io.Closeable;
import java.io.IOException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.function.Consumer;

public class SocketChannelListener implements Closeable,AutoCloseable{
	protected ServerSocketChannel serverSocketChannel;
	public ServerSocketChannel getServerSocketChannel() {
		return serverSocketChannel;
	}

	private volatile boolean flag=true;
	
	private volatile Consumer<SocketChannel>con;
	private Runnable r=new Runnable() {
		@Override
		public void run() {
			while(flag){
				try {
					SocketChannel soce=serverSocketChannel.accept();
					ThreadTool.makeVThreadIfSupport("端口请求处理线程",()->{
							if(con!=null) {
								try {
						con.accept(soce);
								}catch(Exception e) {
									e.printStackTrace();
									try {
										soce.close();
									} catch (IOException er) {
										er.printStackTrace();
									}
								}
							}else {
								try {
									soce.close();
								} catch (IOException e) {
									e.printStackTrace();
								}
						}
					}).start();
				}catch(SocketException e) {
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	};
	private MultiProtocolSocketAddress multiProtocolSocketAddress;
	
	public SocketChannelListener(MultiProtocolSocketAddress multiProtocolSocketAddress) throws  IOException {
		this.multiProtocolSocketAddress = multiProtocolSocketAddress;
			open();
	}
	public SocketChannelListener(ServerSocketChannel tserverSocket) throws  IOException {
		this.serverSocketChannel=tserverSocket;
			open();
	}
	protected void open() throws UnknownHostException, IOException  {
		if(serverSocketChannel==null)
			serverSocketChannel= multiProtocolSocketAddress.listenServerSocketChannel();
		if(serverSocketChannel==null) {
			throw new IOException(multiProtocolSocketAddress.getProtocol()+" unsupport SocketChannel");
		}
		ThreadTool.makeVThread("端口监听线程", r).start();
	}
	public void close() {
		flag=false;
		if(serverSocketChannel!=null) {
			try {
				serverSocketChannel.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			serverSocketChannel=null;
		}
	}
	
	

	public MultiProtocolSocketAddress getMultipurposeSocketAddress() {
		return multiProtocolSocketAddress;
	}

	public Consumer<SocketChannel> getCon() {
		return con;
	}

	public void setCon(Consumer<SocketChannel> con) {
		this.con = con;
	}
	
}
