package net.onrc.onos.core.intent.runtime;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.onrc.onos.core.datagrid.IDatagridService;
import net.onrc.onos.core.datagrid.IEventChannel;
import net.onrc.onos.core.datagrid.IEventChannelListener;
import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
import net.onrc.onos.core.intent.FlowEntry;
import net.onrc.onos.core.intent.IntentOperation;
import net.onrc.onos.core.intent.IntentOperationList;
import net.onrc.onos.core.intent.Intent.IntentState;
import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
//import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;




import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PlanInstallModule implements IFloodlightModule {
    protected volatile IFloodlightProviderService floodlightProvider;
    protected volatile INetworkGraphService networkGraph;
    protected volatile IDatagridService datagridService;
    protected volatile IFlowPusherService flowPusher;
    private PlanCalcRuntime planCalc;
    private PlanInstallRuntime planInstall;
    private EventListener eventListener;
    private IEventChannel<Long, IntentStateList> intentStateChannel;
    private final static Logger log = LoggerFactory.getLogger(PlanInstallModule.class);


    private static final String PATH_INTENT_CHANNEL_NAME = "onos.pathintent";
    private static final String INTENT_STATE_EVENT_CHANNEL_NAME = "onos.pathintent_state";


    @Override
    public void init(FloodlightModuleContext context)
	    throws FloodlightModuleException {
	floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
	networkGraph = context.getServiceImpl(INetworkGraphService.class);
	datagridService = context.getServiceImpl(IDatagridService.class);
	flowPusher = context.getServiceImpl(IFlowPusherService.class);
//	NetworkGraph graph = networkGraph.getNetworkGraph();
	planCalc = new PlanCalcRuntime();
	planInstall = new PlanInstallRuntime(floodlightProvider, flowPusher);
	eventListener = new EventListener();
    }

    class EventListener extends Thread
    	implements IEventChannelListener<Long, IntentOperationList> {

	private BlockingQueue<IntentOperationList> intentQueue = new LinkedBlockingQueue<>();
	private Long key = Long.valueOf(0);

	@Override
	public void run() {
	    while(true) {
		try {
		    IntentOperationList intents = intentQueue.take();
		    //TODO: consider draining the remaining intent lists
		    //      and processing in one big batch
//		    List<IntentOperationList> remaining = new LinkedList<>();
//		    intentQueue.drainTo(remaining);

		    processIntents(intents);
		} catch (InterruptedException e) {
		    log.warn("Error taking from intent queue: {}", e.getMessage());
		}
	    }
	}

	private void processIntents(IntentOperationList intents) {
	    log("start_processIntents");
	    log.debug("Processing OperationList {}", intents);
	    log("begin_computePlan");
	    List<Set<FlowEntry>> plan = planCalc.computePlan(intents);
	    log("end_computePlan");
	    log.debug("Plan: {}", plan);
	    log("begin_installPlan");
	    boolean success = planInstall.installPlan(plan);
	    log("end_installPlan");

	    log("begin_sendInstallNotif");
	    sendNotifications(intents, true, success);
	    log("end_sendInstallNotif");
	    log("finish");
	}

	private void sendNotifications(IntentOperationList intents, boolean installed, boolean success) {
	    IntentStateList states = new IntentStateList();
	    for(IntentOperation i : intents) {
		IntentState newState;
		switch(i.operator) {
		case REMOVE:
		    if(installed) {
			newState = success ? IntentState.DEL_ACK : IntentState.DEL_PENDING;
		    }
		    else {
			newState = IntentState.DEL_REQ;
		    }
		    break;
		case ADD:
		default:
		    if(installed) {
			newState = success ? IntentState.INST_ACK : IntentState.INST_NACK;
		    }
		    else {
			newState = IntentState.INST_REQ;
		    }
		    break;
		}
		states.put(i.intent.getId(), newState);
	    }
	    intentStateChannel.addEntry(key, states);
	    // XXX: Send notifications using the same key every time
	    // and receive them by entryAdded() and entryUpdated()
	    // key += 1;
	}

	@Override
	public void entryAdded(IntentOperationList value) {
	    entryUpdated(value);
	}

	@Override
	public void entryRemoved(IntentOperationList value) {
	    // This channel is a queue, so this method is not needed
	}

	@Override
	public void entryUpdated(IntentOperationList value) {
	    log("start_intentNotifRecv");
	    log("begin_sendReceivedNotif");
	    sendNotifications(value, false, false);
	    log("end_sendReceivedNotif");
	    log("finish");

	    log.debug("Added OperationList {}", value);
	    try {
		intentQueue.put(value);
	    } catch (InterruptedException e) {
		log.warn("Error putting to intent queue: {}", e.getMessage());
	    }
	}
    }

    public static void log(String step) {
	log.error("Time:{}, Step:{}", System.nanoTime(), step);
    }

    @Override
    public void startUp(FloodlightModuleContext context) {
	// start subscriber
	datagridService.addListener(PATH_INTENT_CHANNEL_NAME,
				    	      eventListener,
				              Long.class,
				              IntentOperationList.class);
	eventListener.start();
	// start publisher
	intentStateChannel = datagridService.createChannel(INTENT_STATE_EVENT_CHANNEL_NAME,
						Long.class,
						IntentStateList.class);
    }

    @Override
    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
	Collection<Class<? extends IFloodlightService>> l =
		new ArrayList<Class<? extends IFloodlightService>>();
	l.add(IFloodlightProviderService.class);
	l.add(INetworkGraphService.class);
	l.add(IDatagridService.class);
	l.add(IFlowPusherService.class);
	return l;
    }

    @Override
    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
	// no services, for now
	return null;
    }

    @Override
    public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
	// no services, for now
	return null;
    }

}
