package net.onrc.onos.core.intent;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.Collection;

import net.onrc.onos.core.intent.IntentOperation.Operator;
import net.onrc.onos.core.topology.Link;
import net.onrc.onos.core.topology.LinkEvent;
import net.onrc.onos.core.topology.Port;
import net.onrc.onos.core.topology.Switch;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class PathIntentMapTest {
    Link link12, link23, link24;
    Switch sw1, sw2, sw3, sw4;
    Port port11, port22, port21, port23, port31, port41;
    Path path1, path2;
    PathIntent intent1, intent2;

    @Before
    public void setUp() throws Exception {
        sw1 = createMock(Switch.class);
        sw2 = createMock(Switch.class);
        sw3 = createMock(Switch.class);
        sw4 = createMock(Switch.class);
        expect(sw1.getDpid()).andReturn(1L).anyTimes();
        expect(sw2.getDpid()).andReturn(2L).anyTimes();
        expect(sw3.getDpid()).andReturn(3L).anyTimes();
        expect(sw4.getDpid()).andReturn(4L).anyTimes();
        replay(sw1);
        replay(sw2);
        replay(sw3);
        replay(sw4);

        port11 = createMock(Port.class);
        port22 = createMock(Port.class);
        port21 = createMock(Port.class);
        port23 = createMock(Port.class);
        port31 = createMock(Port.class);
        port41 = createMock(Port.class);
        expect(port11.getNumber()).andReturn(1L).anyTimes();
        expect(port22.getNumber()).andReturn(2L).anyTimes();
        expect(port21.getNumber()).andReturn(1L).anyTimes();
        expect(port23.getNumber()).andReturn(3L).anyTimes();
        expect(port31.getNumber()).andReturn(1L).anyTimes();
        expect(port41.getNumber()).andReturn(1L).anyTimes();
        replay(port11);
        replay(port22);
        replay(port21);
        replay(port23);
        replay(port31);
        replay(port41);

        link12 = createMock(Link.class);
        link23 = createMock(Link.class);
        link24 = createMock(Link.class);
        expect(link12.getCapacity()).andReturn(1000.0).anyTimes();
        expect(link23.getCapacity()).andReturn(1000.0).anyTimes();
        expect(link24.getCapacity()).andReturn(1000.0).anyTimes();
        expect(link12.getSrcSwitch()).andReturn(sw1).anyTimes();
        expect(link23.getSrcSwitch()).andReturn(sw2).anyTimes();
        expect(link24.getSrcSwitch()).andReturn(sw2).anyTimes();
        expect(link12.getSrcPort()).andReturn(port11).anyTimes();
        expect(link23.getSrcPort()).andReturn(port21).anyTimes();
        expect(link24.getSrcPort()).andReturn(port23).anyTimes();
        expect(link12.getDstSwitch()).andReturn(sw2).anyTimes();
        expect(link23.getDstSwitch()).andReturn(sw3).anyTimes();
        expect(link24.getDstSwitch()).andReturn(sw4).anyTimes();
        expect(link12.getDstPort()).andReturn(port22).anyTimes();
        expect(link23.getDstPort()).andReturn(port31).anyTimes();
        expect(link24.getDstPort()).andReturn(port41).anyTimes();
        replay(link12);
        replay(link23);
        replay(link24);

        path1 = new Path();
        path1.add(new LinkEvent(link12));
        path1.add(new LinkEvent(link23));

        path2 = new Path();
        path2.add(new LinkEvent(link12));
        path2.add(new LinkEvent(link24));

        intent1 = new PathIntent("1", path1, 400.0, new Intent("_1"));
        intent2 = new PathIntent("2", path2, 400.0, new Intent("_2"));
    }

    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void testCreate() {
        PathIntentMap intents = new PathIntentMap();
        assertEquals(0, intents.getAllIntents().size());
    }

    @Test
    public void testGetIntentsByDpid() {
        IntentOperationList operations = new IntentOperationList();
        operations.add(Operator.ADD, intent1);
        operations.add(Operator.ADD, intent2);
        assertEquals(2, operations.size());

        PathIntentMap intents = new PathIntentMap();
        intents.executeOperations(operations);
        assertEquals(2, intents.getAllIntents().size());

        Collection<PathIntent> pathIntents = intents.getIntentsByDpid(1L);
        assertEquals(2, pathIntents.size());
        assertTrue(pathIntents.contains(intent1));
        assertTrue(pathIntents.contains(intent2));

        pathIntents = intents.getIntentsByDpid(2L);
        assertEquals(2, pathIntents.size());
        assertTrue(pathIntents.contains(intent1));
        assertTrue(pathIntents.contains(intent2));

        pathIntents = intents.getIntentsByDpid(3L);
        assertEquals(1, pathIntents.size());
        assertTrue(pathIntents.contains(intent1));

        pathIntents = intents.getIntentsByDpid(4L);
        assertEquals(1, pathIntents.size());
        assertTrue(pathIntents.contains(intent2));
    }

    @Test
    public void testGetPathIntentsByPort() {
        IntentOperationList operations = new IntentOperationList();
        operations.add(Operator.ADD, intent1);
        operations.add(Operator.ADD, intent2);
        assertEquals(2, operations.size());

        PathIntentMap intents = new PathIntentMap();
        intents.executeOperations(operations);
        assertEquals(2, intents.getAllIntents().size());

        Collection<PathIntent> pathIntents = intents.getIntentsByPort(1L, 1L);
        assertEquals(2, pathIntents.size());
        assertTrue(pathIntents.contains(intent1));
        assertTrue(pathIntents.contains(intent2));

        pathIntents = intents.getIntentsByPort(2L, 1L);
        assertEquals(1, pathIntents.size());
        assertTrue(pathIntents.contains(intent1));

        pathIntents = intents.getIntentsByPort(2L, 3L);
        assertEquals(1, pathIntents.size());
        assertTrue(pathIntents.contains(intent2));
    }

    @Test
    public void testGetPathIntentsByLink() {
        IntentOperationList operations = new IntentOperationList();
        operations.add(Operator.ADD, intent1);
        operations.add(Operator.ADD, intent2);
        assertEquals(2, operations.size());

        PathIntentMap intents = new PathIntentMap();
        intents.executeOperations(operations);
        assertEquals(2, intents.getAllIntents().size());

        Collection<PathIntent> pathIntents = intents.getIntentsByLink(new LinkEvent(link12));
        assertEquals(2, pathIntents.size());
        assertTrue(pathIntents.contains(intent1));
        assertTrue(pathIntents.contains(intent2));

        pathIntents = intents.getIntentsByLink(new LinkEvent(link23));
        assertEquals(1, pathIntents.size());
        assertTrue(pathIntents.contains(intent1));

        pathIntents = intents.getIntentsByLink(new LinkEvent(link24));
        assertEquals(1, pathIntents.size());
        assertTrue(pathIntents.contains(intent2));
    }

    @Test
    public void testGetAvailableBandwidth() {
        IntentOperationList operations = new IntentOperationList();
        operations.add(Operator.ADD, intent1);
        operations.add(Operator.ADD, intent2);
        assertEquals(2, operations.size());

        PathIntentMap intents = new PathIntentMap();
        intents.executeOperations(operations);
        assertEquals(2, intents.getAllIntents().size());

        assertEquals(200.0, intents.getAvailableBandwidth(link12), 0.0);
    }
}
