Renamed the intent package

net.onrc.onos.intent.* => net.onrc.onos.core.intent.*

Change-Id: Id61f79ed52acf3b91af4ebad2515ac5b7d6dc5e1
diff --git a/src/main/java/net/onrc/onos/core/intent/runtime/PlanCalcRuntime.java b/src/main/java/net/onrc/onos/core/intent/runtime/PlanCalcRuntime.java
new file mode 100644
index 0000000..7c92115
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/intent/runtime/PlanCalcRuntime.java
@@ -0,0 +1,155 @@
+package net.onrc.onos.core.intent.runtime;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.core.intent.FlowEntry;
+import net.onrc.onos.core.intent.Intent;
+import net.onrc.onos.core.intent.IntentOperation;
+import net.onrc.onos.core.intent.IntentOperationList;
+import net.onrc.onos.core.intent.PathIntent;
+import net.onrc.onos.core.intent.ShortestPathIntent;
+import net.onrc.onos.core.intent.IntentOperation.Operator;
+import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
+//import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author Brian O'Connor <bocon@onlab.us>
+ *
+ */
+
+public class PlanCalcRuntime {
+
+//    NetworkGraph graph;
+    private final static Logger log = LoggerFactory.getLogger(PlanCalcRuntime.class);
+
+    public PlanCalcRuntime(/*NetworkGraph graph*/) {
+//	this.graph = graph;
+    }
+
+    public List<Set<FlowEntry>> computePlan(IntentOperationList intentOps) {
+	long start = System.nanoTime();
+	List<Collection<FlowEntry>> flowEntries = computeFlowEntries(intentOps);
+	long step1 = System.nanoTime();
+	List<Set<FlowEntry>> plan = buildPhases(flowEntries);
+	long step2 = System.nanoTime();
+	log.error("MEASUREMENT: Compute flow entries: {} ns, Build phases: {} ns", 
+		  (step1 - start), (step2 - step1));
+	return plan;
+    }
+
+    private List<Collection<FlowEntry>> computeFlowEntries(IntentOperationList intentOps) {
+	List<Collection<FlowEntry>> flowEntries = new LinkedList<>();
+	for(IntentOperation i : intentOps) {
+	    if(!(i.intent instanceof PathIntent)) {
+		log.warn("Not a path intent: {}", i);
+		continue;
+	    }
+	    PathIntent intent = (PathIntent) i.intent;
+	    Intent parent = intent.getParentIntent();
+	    long srcPort, dstPort;
+	    long lastDstSw = -1, lastDstPort = -1;
+	    MACAddress srcMac, dstMac;
+	    if(parent instanceof ShortestPathIntent) {
+		ShortestPathIntent pathIntent = (ShortestPathIntent) parent;
+//		Switch srcSwitch = graph.getSwitch(pathIntent.getSrcSwitchDpid());
+//		srcPort = srcSwitch.getPort(pathIntent.getSrcPortNumber());
+		srcPort = pathIntent.getSrcPortNumber();
+		srcMac = MACAddress.valueOf(pathIntent.getSrcMac());
+		dstMac = MACAddress.valueOf(pathIntent.getDstMac());
+//		Switch dstSwitch = graph.getSwitch(pathIntent.getDstSwitchDpid());
+		lastDstSw = pathIntent.getDstSwitchDpid();
+//		lastDstPort = dstSwitch.getPort(pathIntent.getDstPortNumber());
+		lastDstPort = pathIntent.getDstPortNumber();
+	    }
+	    else {
+		log.warn("Unsupported Intent: {}", parent);
+		continue;
+	    }
+	    List<FlowEntry> entries = new ArrayList<>();
+	    for(LinkEvent linkEvent : intent.getPath()) {
+//		Link link = graph.getLink(linkEvent.getSrc().getDpid(),
+//			  linkEvent.getSrc().getNumber(),
+//			  linkEvent.getDst().getDpid(),
+//			  linkEvent.getDst().getNumber());
+//		Switch sw = link.getSrcSwitch();
+		long sw = linkEvent.getSrc().getDpid();
+//		dstPort = link.getSrcPort();
+		dstPort = linkEvent.getSrc().getNumber();
+		FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
+		entries.add(fe);
+//		srcPort = link.getDstPort();
+		srcPort = linkEvent.getDst().getNumber();
+	    }
+	    if(lastDstSw >= 0 && lastDstPort >= 0) {
+		//Switch sw = lastDstPort.getSwitch();
+		long sw = lastDstSw;
+		dstPort = lastDstPort;
+		FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
+		entries.add(fe);
+	    }
+	    // install flow entries in reverse order
+	    Collections.reverse(entries);
+	    flowEntries.add(entries);
+	}
+	return flowEntries;
+    }
+
+    private List<Set<FlowEntry>> buildPhases(List<Collection<FlowEntry>> flowEntries) {
+	Map<FlowEntry, Integer> map = new HashMap<>();
+	List<Set<FlowEntry>> plan = new ArrayList<>();
+	for(Collection<FlowEntry> c : flowEntries) {
+	    for(FlowEntry e : c) {
+		Integer i = map.get(e);
+		if(i == null) {
+		    i = Integer.valueOf(0);
+		}
+		switch(e.getOperator()) {
+		case ADD:
+		    i += 1;
+		    break;
+		case REMOVE:
+		    i -= 1;
+		    break;
+		default:
+		    break;
+		}
+		map.put(e, i);
+		// System.out.println(e + " " + e.getOperator());
+	    }
+	}
+
+	// really simple first iteration of plan
+	//TODO: optimize the map in phases
+	Set<FlowEntry> phase = new HashSet<>();
+	for(FlowEntry e : map.keySet()) {
+	    Integer i = map.get(e);
+	    if(i == 0) {
+		continue;
+	    }
+	    else if(i > 0) {
+		e.setOperator(Operator.ADD);
+	    }
+	    else if(i < 0) {
+		e.setOperator(Operator.REMOVE);
+	    }
+	    phase.add(e);
+	}
+	plan.add(phase);
+
+	return plan;
+    }
+}