package hh.dejsem.net;

import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;

import hh.dejsem.K;
import hh.lib.D;

public class NetSslChnIO extends NetSslChIO {
	/**----------------------------------------------------------
	 * SSL non-blocking network IO (SSL engine)
	 * ----------------------------------------------------------*/

	NetSslChnIO(D d) throws Exception { super(d); }

	@Override
	void wrapAndPut(ByteBuffer out, ByteBuffer in) throws Exception {
		do {
			wrap(out);
			if(sslOut.position() == 0) break;
			putSslOut();
		} while(needWrap());
		if(needUnwrap()) selectAndUnwrap(in, out);
	}

	void selectAndUnwrap(ByteBuffer in, ByteBuffer out) throws Exception {
		if(d.ll(5)) d.l("select reading...");
		select(SelectionKey.OP_READ);
		getAndUnwrap(in, out);
	}

	void selectAndWrap(ByteBuffer out, ByteBuffer in) throws Exception {
		if(d.ll(5)) d.l("select writing...");
		select(SelectionKey.OP_WRITE);
		wrapAndPut(out, in);
	}

	void select(int flag) throws Exception {
		register(flag);
		int selection = selector.select(K.socketTO);
		selector.selectedKeys().remove(sk);
		if(selection == 0) throw new Exception("timeout on net oper");
	}

	void terminateServer(ByteBuffer dataIn) throws Exception {
		closeOut();
		selectAndUnwrap(dataIn, ByteBuffer.allocate(0));
		closeSocket();
	}

	@Override
	void configureSocket() throws Exception {
		sc.configureBlocking(false);
		if(selector == null) selector = Selector.open();
		register(SelectionKey.OP_READ);
	}

	void register(int flag) throws Exception { sk = sc.register(selector, flag); }
}
