package org.kne.cloud.network.srv6;

import java.io.IOException;
import java.lang.ref.Cleaner;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.function.BiConsumer;

import org.kne.cloud.network.klalb.KLALBController;
import org.kne.opencl64.Releaser;

public class KLALBRoutingProtocolAPIServer {
	private KLALBController controller;
	private KLALBRoutingProtocol routingProtocol;
	

	private static final Cleaner clr=Cleaner.create();
	
	private BiConsumer<SocketAddress, JsonDataPacket> rec=(addr,data)->{
		try {
		KLALBRoutingProtocolJsonData dataobj= data.getDecodedData();
		InetSocketAddress addrs=(InetSocketAddress) addr;
		switch(dataobj.getType()){
		case KLALBRoutingProtocolJsonData.OPEN_LINES_REQ:
			if(controller.getConfigItem()==null||(!controller.getConfigItem().isDenyLineTableQuery())) {
			KLALBRoutingProtocolJsonData json=new KLALBRoutingProtocolJsonData(KLALBRoutingProtocolJsonData.OPEN_LINES_RESP,dataobj.getUuid(),controller.getSelflineTable());
				routingProtocol.sendJsonPacketToAddress(new JsonDataPacket(json),addr);
			}
			break;
		}
		} catch (IOException e) {
			e.printStackTrace();
		}
	};

	public KLALBRoutingProtocolAPIServer(KLALBRoutingProtocol routingProtocol,KLALBController controller) {
		this.controller=controller;
		this.routingProtocol=routingProtocol;
		routingProtocol.addReceiver(rec);
		this.releaser=new KLALBRoutingProtocolAPIServerReleaser(this.routingProtocol,rec);
		clr.register(this, releaser);
	}

	public KLALBController getController() {
		return controller;
	}

	public KLALBRoutingProtocol getRoutingProtocol() {
		return routingProtocol;
	}
	
	
private KLALBRoutingProtocolAPIServerReleaser releaser;
	
	public void close() {
		releaser.run();
	}
	
	
	public boolean isClosed() {
		return releaser.isReleased();
	}
	
}
class KLALBRoutingProtocolAPIServerReleaser extends Releaser<BiConsumer<SocketAddress, JsonDataPacket>>{

	private KLALBRoutingProtocol routingProtocol;

	public KLALBRoutingProtocolAPIServerReleaser(KLALBRoutingProtocol routingProtocol,BiConsumer<SocketAddress, JsonDataPacket> resource) {
		super(resource);
		this.routingProtocol=routingProtocol;
	}

	@Override
	protected void release(BiConsumer<SocketAddress, JsonDataPacket> resource) {
		routingProtocol.removeReceiver(resource);
	}
}