package net.onrc.onos.core.intent;

import net.onrc.onos.core.topology.Link;
import net.onrc.onos.core.topology.LinkImpl;
import net.onrc.onos.core.topology.NetworkGraph;
import net.onrc.onos.core.topology.NetworkGraphImpl;
import net.onrc.onos.core.topology.Port;
import net.onrc.onos.core.topology.Switch;
import net.onrc.onos.core.topology.SwitchImpl;

/**
 * A mock class of NetworkGraph.
 * This class should be used only by test codes.
 *
 * @author Toshio Koide (t-koide@onlab.us)
 */
public class MockNetworkGraph extends NetworkGraphImpl {
    public static Long LOCAL_PORT = 0xFFFEL;
    public SwitchImpl sw1, sw2, sw3, sw4;

    class DetachableLinkImpl extends LinkImpl {
        public DetachableLinkImpl(NetworkGraph graph, Port srcPort, Port dstPort) {
            super(graph, srcPort, dstPort);
        }

        public void detachFromGraph() {
            unsetFromPorts();
        }
    }

    public Switch addSwitch(Long switchId) {
        SwitchImpl sw = new SwitchImpl(this, switchId);
        this.putSwitch(sw);
        return sw;
    }

    public Link addLink(Long srcDpid, Long srcPortNo, Long dstDpid, Long dstPortNo) {
        return new DetachableLinkImpl(
                this,
                getSwitch(srcDpid).getPort(srcPortNo),
                getSwitch(dstDpid).getPort(dstPortNo));
    }

    public Link[] addBidirectionalLinks(Long srcDpid, Long srcPortNo, Long dstDpid, Long dstPortNo) {
        Link[] links = new Link[2];
        links[0] = addLink(srcDpid, srcPortNo, dstDpid, dstPortNo);
        links[1] = addLink(dstDpid, dstPortNo, srcDpid, srcPortNo);

        return links;
    }

    /**
     * create sample topology of 4 switches and 5 bidirectional links.
     * <pre>
     * [1] --- [2]
     *  |    /  |
     *  |  /    |
     * [4] --- [3]
     * </pre>
     */
    public void createSampleTopology1() {
        sw1 = (SwitchImpl) addSwitch(1L);
        sw1.addPort(LOCAL_PORT);
        sw2 = (SwitchImpl) addSwitch(2L);
        sw2.addPort(LOCAL_PORT);
        sw3 = (SwitchImpl) addSwitch(3L);
        sw3.addPort(LOCAL_PORT);
        sw4 = (SwitchImpl) addSwitch(4L);
        sw4.addPort(LOCAL_PORT);

        sw1.addPort(12L); // sw1 -> sw2
        sw1.addPort(14L); // sw1 -> sw4
        sw2.addPort(21L); // sw2 -> sw1
        sw2.addPort(23L); // sw2 -> sw3
        sw2.addPort(24L); // sw2 -> sw4
        sw3.addPort(32L); // sw3 -> sw2
        sw3.addPort(34L); // sw3 -> sw4
        sw4.addPort(41L); // sw4 -> sw1
        sw4.addPort(42L); // sw4 -> sw2
        sw4.addPort(43L); // sw4 -> sw3

        addBidirectionalLinks(1L, 12L, 2L, 21L);
        addBidirectionalLinks(2L, 23L, 3L, 32L);
        addBidirectionalLinks(3L, 34L, 4L, 43L);
        addBidirectionalLinks(4L, 41L, 1L, 14L);
        addBidirectionalLinks(2L, 24L, 4L, 42L);

        // set capacity of all links to 1000Mbps
        for (Link link : getLinks()) {
            ((LinkImpl) link).setCapacity(1000.0);
        }
    }

    public void removeLink(Long srcDpid, Long srcPortNo, Long dstDpid, Long dstPortNo) {
        DetachableLinkImpl link = (DetachableLinkImpl) getSwitch(srcDpid).getPort(srcPortNo).getOutgoingLink();
        if (link.getDstSwitch().getDpid().equals(dstDpid) && link.getDstPort().getNumber().equals(dstPortNo)) {
            link.detachFromGraph();
        }
    }
}
