/**
*    Copyright 2011, Big Switch Networks, Inc. 
*    Originally created by David Erickson, Stanford University
* 
*    Licensed under the Apache License, Version 2.0 (the "License"); you may
*    not use this file except in compliance with the License. You may obtain
*    a copy of the License at
*
*         http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
*    License for the specific language governing permissions and limitations
*    under the License.
**/

package net.onrc.onos.ofcontroller.linkdiscovery.internal;

import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IFloodlightProviderService.Role;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.test.MockThreadPoolService;
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.restserver.RestApiServer;
import net.floodlightcontroller.routing.IRoutingService;
import net.floodlightcontroller.routing.Link;
import net.floodlightcontroller.test.FloodlightTestCase;
import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.floodlightcontroller.topology.ITopologyService;
import net.floodlightcontroller.topology.NodePortTuple;
import net.floodlightcontroller.topology.TopologyManager;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;

import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author David Erickson (daviderickson@cs.stanford.edu)
 */
public class LinkDiscoveryManagerTest extends FloodlightTestCase {

    private TestLinkDiscoveryManager ldm;
    protected final static Logger log = LoggerFactory.getLogger(LinkDiscoveryManagerTest.class);
    
    public class TestLinkDiscoveryManager extends LinkDiscoveryManager {
        public boolean isSendLLDPsCalled = false;
        public boolean isClearLinksCalled = false;

        @Override
        protected void discoverOnAllPorts() {
            isSendLLDPsCalled = true;
            super.discoverOnAllPorts();
        }

        public void reset() {
            isSendLLDPsCalled = false;
            isClearLinksCalled = false;
        }
    }
    
    public LinkDiscoveryManager getTopology() {
        return ldm;
    }

    public IOFSwitch createMockSwitch(Long id) {
        IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
        expect(mockSwitch.getId()).andReturn(id).anyTimes();
        return mockSwitch;
    }

    @Before
    public void setUp() throws Exception {
        super.setUp();
        FloodlightModuleContext cntx = new FloodlightModuleContext();
        ldm = new TestLinkDiscoveryManager();
        TopologyManager routingEngine = new TopologyManager();
        ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
        MockThreadPoolService tp = new MockThreadPoolService();
        RestApiServer restApi = new RestApiServer();
        cntx.addService(IRestApiService.class, restApi);
        cntx.addService(IThreadPoolService.class, tp);
        cntx.addService(IRoutingService.class, routingEngine);
        cntx.addService(ILinkDiscoveryService.class, ldm);
        cntx.addService(ITopologyService.class, ldm);
        cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
        restApi.init(cntx);
        tp.init(cntx);
        routingEngine.init(cntx);
        ldm.init(cntx);
        restApi.startUp(cntx);
        tp.startUp(cntx);
        routingEngine.startUp(cntx);
        ldm.startUp(cntx);

        IOFSwitch sw1 = createMockSwitch(1L);
        IOFSwitch sw2 = createMockSwitch(2L);
        Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
        switches.put(1L, sw1);
        switches.put(2L, sw2);
        getMockFloodlightProvider().setSwitches(switches);
        replay(sw1, sw2);
    }

    @Test
    public void testAddOrUpdateLink() throws Exception {
        LinkDiscoveryManager topology = getTopology();

        Link lt = new Link(1L, 2, 2L, 1);
        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
                                     System.currentTimeMillis(), null,
                                     0, 0);
        topology.addOrUpdateLink(lt, info);


        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
        NodePortTuple dstNpt = new NodePortTuple(2L, 1);

        // check invariants hold
        assertNotNull(topology.switchLinks.get(lt.getSrc()));
        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
        assertNotNull(topology.portLinks.get(srcNpt));
        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
        assertNotNull(topology.portLinks.get(dstNpt));
        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
        assertTrue(topology.links.containsKey(lt));
    }

    @Test
    public void testDeleteLink() throws Exception {
        LinkDiscoveryManager topology = getTopology();

        Link lt = new Link(1L, 2, 2L, 1);
        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
                                     System.currentTimeMillis(), null,
                                     0, 0);
        topology.addOrUpdateLink(lt, info);
        topology.deleteLinks(Collections.singletonList(lt), "Test");

        // check invariants hold
        assertNull(topology.switchLinks.get(lt.getSrc()));
        assertNull(topology.switchLinks.get(lt.getDst()));
        assertNull(topology.portLinks.get(lt.getSrc()));
        assertNull(topology.portLinks.get(lt.getDst()));
        assertTrue(topology.links.isEmpty());
    }

    @Test
    public void testAddOrUpdateLinkToSelf() throws Exception {
        LinkDiscoveryManager topology = getTopology();

        Link lt = new Link(1L, 2, 2L, 3);
        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
        NodePortTuple dstNpt = new NodePortTuple(2L, 3);

        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
                                     System.currentTimeMillis(), null,
                                     0, 0);
        topology.addOrUpdateLink(lt, info);

        // check invariants hold
        assertNotNull(topology.switchLinks.get(lt.getSrc()));
        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
        assertNotNull(topology.portLinks.get(srcNpt));
        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
        assertNotNull(topology.portLinks.get(dstNpt));
        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
        assertTrue(topology.links.containsKey(lt));
    }

    @Test
    public void testDeleteLinkToSelf() throws Exception {
        LinkDiscoveryManager topology = getTopology();

        Link lt = new Link(1L, 2, 1L, 3);
        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
        NodePortTuple dstNpt = new NodePortTuple(2L, 3);

        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
                                     System.currentTimeMillis(), null,
                                     0, 0);
        topology.addOrUpdateLink(lt, info);
        topology.deleteLinks(Collections.singletonList(lt), "Test to self");

        // check invariants hold
        assertNull(topology.switchLinks.get(lt.getSrc()));
        assertNull(topology.switchLinks.get(lt.getDst()));
        assertNull(topology.portLinks.get(srcNpt));
        assertNull(topology.portLinks.get(dstNpt));
        assertTrue(topology.links.isEmpty());
    }

    @Test
    public void testRemovedSwitch() {
        LinkDiscoveryManager topology = getTopology();

        Link lt = new Link(1L, 2, 2L, 1);
        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
        NodePortTuple dstNpt = new NodePortTuple(2L, 1);
        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
                                     System.currentTimeMillis(), null,
                                     0, 0);
        topology.addOrUpdateLink(lt, info);

        IOFSwitch sw1 = getMockFloodlightProvider().getSwitches().get(1L);
        IOFSwitch sw2 = getMockFloodlightProvider().getSwitches().get(2L);
        // Mock up our expected behavior
        topology.removedSwitch(sw1);
        verify(sw1, sw2);

        // check invariants hold
        assertNull(topology.switchLinks.get(lt.getSrc()));
        assertNull(topology.switchLinks.get(lt.getDst()));
        assertNull(topology.portLinks.get(srcNpt));
        assertNull(topology.portLinks.get(dstNpt));
        assertTrue(topology.links.isEmpty());
    }

    @Test
    public void testRemovedSwitchSelf() {
        LinkDiscoveryManager topology = getTopology();
        IOFSwitch sw1 = createMockSwitch(1L);
        replay(sw1);
        Link lt = new Link(1L, 2, 1L, 3);
        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
                                     System.currentTimeMillis(), null,
                                     0, 0);
        topology.addOrUpdateLink(lt, info);

        // Mock up our expected behavior
        topology.removedSwitch(sw1);

        verify(sw1);
        // check invariants hold
        assertNull(topology.switchLinks.get(lt.getSrc()));
        assertNull(topology.portLinks.get(lt.getSrc()));
        assertNull(topology.portLinks.get(lt.getDst()));
        assertTrue(topology.links.isEmpty());
    }

    @Test
    public void testAddUpdateLinks() throws Exception {
        LinkDiscoveryManager topology = getTopology();

        Link lt = new Link(1L, 1, 2L, 1);
        NodePortTuple srcNpt = new NodePortTuple(1L, 1);
        NodePortTuple dstNpt = new NodePortTuple(2L, 1);
        
        LinkInfo info;

        info = new LinkInfo(System.currentTimeMillis() - 40000,
                            System.currentTimeMillis() - 40000, null,
                                     0, 0);
        topology.addOrUpdateLink(lt, info);

        // check invariants hold
        assertNotNull(topology.switchLinks.get(lt.getSrc()));
        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
        assertNotNull(topology.portLinks.get(srcNpt));
        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
        assertNotNull(topology.portLinks.get(dstNpt));
        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
        assertTrue(topology.links.containsKey(lt));
        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
                topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
                topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);

        topology.timeoutLinks();


        info = new LinkInfo(System.currentTimeMillis(),/* firstseen */
                            null,/* unicast */
                            System.currentTimeMillis(), 0, 0);
        topology.addOrUpdateLink(lt, info);
        assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
        assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));


        // Add a link info based on info that woudld be obtained from unicast LLDP
        // Setting the unicast LLDP reception time to be 40 seconds old, so we can use
        // this to test timeout after this test.  Although the info is initialized
        // with LT_OPENFLOW_LINK, the link property should be changed to LT_NON_OPENFLOW
        // by the addOrUpdateLink method.
        info = new LinkInfo(System.currentTimeMillis() - 40000,
                            System.currentTimeMillis() - 40000, null, 0, 0);
        topology.addOrUpdateLink(lt, info);
        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
                topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
                topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);

        // Expect to timeout the unicast Valid Time, but not the multicast Valid time
        // So the link type should go back to non-openflow link.
        topology.timeoutLinks();
        assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
        assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));

        // Set the multicastValidTime to be old and see if that also times out.
        info = new LinkInfo(System.currentTimeMillis() - 40000,
                            null, System.currentTimeMillis() - 40000, 0, 0);
        topology.addOrUpdateLink(lt, info);
        topology.timeoutLinks();
        assertTrue(topology.links.get(lt) == null);
        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
                topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
                topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);


        // Test again only with multicast LLDP
        info = new LinkInfo(System.currentTimeMillis() - 40000,
                            null, System.currentTimeMillis() - 40000, 0, 0);
        topology.addOrUpdateLink(lt, info);
        assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
        assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));

        // Call timeout and check if link is no longer present.
        topology.timeoutLinks();
        assertTrue(topology.links.get(lt) == null);
        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
                topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
                topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);

        // Start clean and see if loops are also added.
        lt = new Link(1L, 1, 1L, 2);
        srcNpt = new NodePortTuple(1L, 1);
        dstNpt = new NodePortTuple(1L, 2);
        info = new LinkInfo(System.currentTimeMillis() - 40000,
                            null, System.currentTimeMillis() - 40000, 0, 0);
        topology.addOrUpdateLink(lt, info);
        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));


        // Start clean and see if loops are also added.
        lt = new Link(1L, 1, 1L, 3);
        srcNpt = new NodePortTuple(1L, 1);
        dstNpt = new NodePortTuple(1L, 3);
        info = new LinkInfo(System.currentTimeMillis() - 40000,
                            null, System.currentTimeMillis() - 40000, 0, 0);
        topology.addOrUpdateLink(lt, info);
        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));


        // Start clean and see if loops are also added.
        lt = new Link(1L, 4, 1L, 5);
        srcNpt = new NodePortTuple(1L, 4);
        dstNpt = new NodePortTuple(1L, 5);
        info = new LinkInfo(System.currentTimeMillis() - 40000,
                            null, System.currentTimeMillis() - 40000, 0, 0);
        topology.addOrUpdateLink(lt, info);
        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));


        // Start clean and see if loops are also added.
        lt = new Link(1L, 3, 1L, 5);
        srcNpt = new NodePortTuple(1L, 3);
        dstNpt = new NodePortTuple(1L, 5);
        info = new LinkInfo(System.currentTimeMillis() - 40000,
                            null, System.currentTimeMillis() - 40000, 0, 0);
        topology.addOrUpdateLink(lt, info);
        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
    }

    @Test
    public void testHARoleChange() throws Exception {
        LinkDiscoveryManager topology = getTopology();
        IOFSwitch sw1 = createMockSwitch(1L);
        IOFSwitch sw2 = createMockSwitch(2L);
        replay(sw1, sw2);
        Link lt = new Link(1L, 2, 2L, 1);
        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
        NodePortTuple dstNpt = new NodePortTuple(2L, 1);
        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
                                     System.currentTimeMillis(), null,
                                     0, 0);
        topology.addOrUpdateLink(lt, info);

        // check invariants hold
        assertNotNull(topology.switchLinks.get(lt.getSrc()));
        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
        assertNotNull(topology.portLinks.get(srcNpt));
        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
        assertNotNull(topology.portLinks.get(dstNpt));
        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
        assertTrue(topology.links.containsKey(lt));
        
        // check that it clears from memory
        getMockFloodlightProvider().dispatchRoleChanged(null, Role.SLAVE);
        assertTrue(topology.switchLinks.isEmpty());
        getMockFloodlightProvider().dispatchRoleChanged(Role.SLAVE, Role.MASTER);
        // check that lldps were sent
        assertTrue(ldm.isSendLLDPsCalled);
        ldm.reset();
    }
}
