package net.onrc.onos.core.datagrid.web;

import java.util.ArrayList;
import java.util.SortedMap;
import java.util.TreeMap;

import net.onrc.onos.core.intent.Intent;
import net.onrc.onos.core.intent.IntentMap;
import net.onrc.onos.core.intent.PathIntent;
import net.onrc.onos.core.intent.ShortestPathIntent;
import net.onrc.onos.core.intent.Intent.IntentState;
import net.onrc.onos.core.intent.runtime.IPathCalcRuntimeService;
import net.onrc.onos.core.topology.LinkEvent;
import net.onrc.onos.core.topology.Path;
import net.onrc.onos.core.util.CallerId;
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.FlowEntry;
import net.onrc.onos.core.util.FlowId;
import net.onrc.onos.core.util.FlowPath;
import net.onrc.onos.core.util.FlowPathType;
import net.onrc.onos.core.util.FlowPathUserState;
import net.onrc.onos.core.util.Port;
import net.onrc.onos.core.util.SwitchPort;

import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * REST API call to get a summary of Flow Paths.
 *
 * NOTE: This REST API call is needed for the ONOS GUI.
 *
 * GET /wm/onos/datagrid/get/ng-flows/summary/json
 */
public class GetNGFlowsSummaryResource extends ServerResource {
    public static final Logger log = LoggerFactory.getLogger(GetNGFlowsSummaryResource.class);

    @Get("json")
    public ArrayList<FlowPath> retrieve() {
        ArrayList<FlowPath> result = new ArrayList<>();
        SortedMap<Long, FlowPath> sortedFlowPaths = new TreeMap<>();

        IPathCalcRuntimeService pathRuntime =
                (IPathCalcRuntimeService) getContext().
                        getAttributes().get(IPathCalcRuntimeService.class.getCanonicalName());
        log.debug("Get NG Flows Summary");


        IntentMap parentIntentMap = pathRuntime.getHighLevelIntents();
        IntentMap intentMap = pathRuntime.getPathIntents();
        for (Intent parentIntent : parentIntentMap.getAllIntents()) {
            // Get only installed Shortest Paths
            if (parentIntent.getState() != IntentState.INST_ACK)
                continue;
            if (!(parentIntent instanceof ShortestPathIntent))
                continue;
            ShortestPathIntent spIntent = (ShortestPathIntent) parentIntent;

            // Get the Path Intent
            Intent intent = intentMap.getIntent(spIntent.getPathIntentId());
            if (!(intent instanceof PathIntent))
                continue;
            PathIntent pathIntent = (PathIntent) intent;

            // Decode the Shortest Path ID
            String applnIntentId = parentIntent.getId();
            String intentId = applnIntentId.split(":")[1];

            // Create the Flow Path
            FlowId flowId = new FlowId(intentId);
            FlowPath flowPath = new FlowPath();
            flowPath.setFlowId(flowId);
            sortedFlowPaths.put(flowPath.flowId().value(), flowPath);

            flowPath.setInstallerId(new CallerId("E"));
            flowPath.setFlowEntryActions(null);
            flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
            flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);

            // Setup the Source and Destination DPID and Port
            SwitchPort srcPort = flowPath.dataPath().srcPort();
            SwitchPort dstPort = flowPath.dataPath().dstPort();
            srcPort.setDpid(new Dpid(spIntent.getSrcSwitchDpid()));
            srcPort.setPort(new Port((short) spIntent.getSrcPortNumber()));
            dstPort.setDpid(new Dpid(spIntent.getDstSwitchDpid()));
            dstPort.setPort(new Port((short) spIntent.getDstPortNumber()));

            // Extract the Flow Entries
            Path path = pathIntent.getPath();
            FlowEntry flowEntry;
            ArrayList<FlowEntry> flowEntries = new ArrayList<>();
            for (LinkEvent linkEvent : path) {
                Dpid dpid = new Dpid(linkEvent.getSrc().getDpid());
                flowEntry = new FlowEntry();
                flowEntry.setDpid(dpid);
                flowEntries.add(flowEntry);
            }
            // Add the final Flow Entry
            flowEntry = new FlowEntry();
            flowEntry.setDpid(new Dpid(spIntent.getDstSwitchDpid()));
            flowEntries.add(flowEntry);
            flowPath.dataPath().setFlowEntries(flowEntries);
        }

        // Prepare the return result
        for (FlowPath flowPath : sortedFlowPaths.values())
            result.add(flowPath);

        return result;
    }
}
