package org.kne.cloud.network.klalb;

import java.io.IOException;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketOption;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Set;
import org.kne.cloud.network.kltp.KLTPInputStream;
import org.kne.cloud.network.kltp.KLTPOutputStream;

public class KLALBVirtualSocketChannel extends SocketChannel{

	private KLALBController controller;

	private KLALBVirtualSocket socket;
	
	protected KLALBVirtualSocketChannel(KLALBController controller) throws SocketException {
		super(null);
		this.controller=controller;
		this.socket=new KLALBVirtualSocket(controller);
		socket.channel=this;
	}

	protected KLALBVirtualSocketChannel(KLALBController controller, KLALBVirtualSocket sock) {
		super(null);
		this.controller=controller;
		this.socket=sock;
		socket.channel=this;
	}

	public static SocketChannel open(KLALBController controller) throws SocketException {
		return new KLALBVirtualSocketChannel(controller);
	}

	public KLALBController getController() {
		return controller;
	}

	@Override
	public <T> T getOption(SocketOption<T> name) throws IOException {
		// TODO 自动生成的方法存根
		return null;
	}

	@Override
	public Set<SocketOption<?>> supportedOptions() {
		// TODO 自动生成的方法存根
		return null;
	}

	@Override
	public SocketChannel bind(SocketAddress local) throws IOException {
		socket.bind(local);
		return this;
	}

	@Override
	public <T> SocketChannel setOption(SocketOption<T> name, T value) throws IOException {
		// TODO 自动生成的方法存根
		return null;
	}

	@Override
	public SocketChannel shutdownInput() throws IOException {
		socket.shutdownInput();
		return this;
	}

	@Override
	public SocketChannel shutdownOutput() throws IOException {
		socket.shutdownOutput();
		return this;
	}

	@Override
	public Socket socket() {
		return socket;
	}

	@Override
	public boolean isConnected() {
		return socket.isConnected();
	}

	@Override
	public boolean isConnectionPending() {
		return socket.isConnectionPending();
	}

	@Override
	public boolean connect(SocketAddress remote) throws IOException {
		socket.connect(remote);
		return true;
	}

	@Override
	public boolean finishConnect() throws IOException {
		return true;
	}

	@Override
	public SocketAddress getRemoteAddress() throws IOException {
		return socket.getRemoteSocketAddress();
	}

	@Override
	public int read(ByteBuffer dst) throws IOException {
		return ((KLTPInputStream)socket.getInputStream()).read(dst);
	}

	@Override
	public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
		return ((KLTPInputStream)socket.getInputStream()).read(dsts,offset,length);
	}

	@Override
	public int write(ByteBuffer src) throws IOException {
		return ((KLTPOutputStream)socket.getOutputStream()).write(src);
	}

	@Override
	public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
		return ((KLTPOutputStream)socket.getOutputStream()).write(srcs,offset,length);
	}

	@Override
	public SocketAddress getLocalAddress() throws IOException {
		return socket.getLocalSocketAddress();
	}

	@Override
	protected void implCloseSelectableChannel() throws IOException {
		socket.close();
	}

	@Override
	protected void implConfigureBlocking(boolean block) throws IOException {
		if(!block) {
			throw new UnsupportedOperationException("Please use VirtualThread to configure Asynchronous IO");
		}
	}

	public boolean isAutoFlush() throws IOException {
		return ((KLTPOutputStream)socket.getOutputStream()).isAutoFlush();
	}
	public void setAutoFlush(boolean b) throws IOException {
		((KLTPOutputStream)socket.getOutputStream()).setAutoFlush(b);
	}
	
	public void flush() throws IOException {
		((KLTPOutputStream)socket.getOutputStream()).flush();
	}
}
