/**
*    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.floodlightcontroller.core.internal;

import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.isA;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.same;
import static org.easymock.EasyMock.verify;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import net.floodlightcontroller.core.FloodlightContext;
import net.floodlightcontroller.core.FloodlightProvider;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IFloodlightProviderService.Role;
import net.floodlightcontroller.core.IListener.Command;
import net.floodlightcontroller.core.IOFMessageListener;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.IOFSwitchListener;
import net.floodlightcontroller.core.IUpdate;
import net.floodlightcontroller.core.internal.Controller.SwitchUpdate;
import net.floodlightcontroller.core.internal.Controller.SwitchUpdateType;
import net.floodlightcontroller.core.internal.OFChannelState.HandshakeState;
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.test.FloodlightTestCase;
import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryService;
import net.onrc.onos.core.linkdiscovery.internal.LinkDiscoveryManager;
import net.onrc.onos.core.main.IOFSwitchPortListener;
import net.onrc.onos.core.packet.ARP;
import net.onrc.onos.core.packet.Ethernet;
import net.onrc.onos.core.packet.IPacket;
import net.onrc.onos.core.packet.IPv4;
import net.onrc.onos.core.registry.IControllerRegistryService;
import net.onrc.onos.core.registry.StandaloneRegistry;

import org.easymock.Capture;
import org.easymock.EasyMock;
import org.jboss.netty.channel.Channel;
import org.junit.Test;
import org.openflow.protocol.OFError;
import org.openflow.protocol.OFError.OFBadRequestCode;
import org.openflow.protocol.OFError.OFErrorType;
import org.openflow.protocol.OFFeaturesReply;
import org.openflow.protocol.OFPacketIn;
import org.openflow.protocol.OFPacketIn.OFPacketInReason;
import org.openflow.protocol.OFPhysicalPort;
import org.openflow.protocol.OFPhysicalPort.OFPortConfig;
import org.openflow.protocol.OFPhysicalPort.OFPortState;
import org.openflow.protocol.OFPortStatus;
import org.openflow.protocol.OFPortStatus.OFPortReason;
import org.openflow.protocol.OFStatisticsReply;
import org.openflow.protocol.OFType;
import org.openflow.protocol.OFVendor;
import org.openflow.protocol.factory.BasicFactory;
import org.openflow.protocol.statistics.OFFlowStatisticsReply;
import org.openflow.protocol.statistics.OFStatistics;
import org.openflow.protocol.statistics.OFStatisticsType;
import org.openflow.util.HexString;
import org.openflow.vendor.nicira.OFNiciraVendorData;
import org.openflow.vendor.nicira.OFRoleReplyVendorData;

/**
 *
 * @author David Erickson (daviderickson@cs.stanford.edu)
 */
public class ControllerTest extends FloodlightTestCase {
   
    private Controller controller;
    private MockThreadPoolService tp;

    @Override
    public void setUp() throws Exception {
        super.setUp();
        FloodlightModuleContext fmc = new FloodlightModuleContext();
        
        FloodlightProvider cm = new FloodlightProvider();
        controller = (Controller)cm.getServiceImpls().get(IFloodlightProviderService.class);
        fmc.addService(IFloodlightProviderService.class, controller);
        
        RestApiServer restApi = new RestApiServer();
        fmc.addService(IRestApiService.class, restApi);
   
        tp = new MockThreadPoolService();
        fmc.addService(IThreadPoolService.class, tp);
        
        // Following added by ONOS
        // TODO replace with mock if further testing is needed.
        StandaloneRegistry sr = new StandaloneRegistry();
        fmc.addService(IControllerRegistryService.class, sr );
        LinkDiscoveryManager linkDiscovery = new LinkDiscoveryManager();
        fmc.addService(ILinkDiscoveryService.class, linkDiscovery);

        
        restApi.init(fmc);
        cm.init(fmc);
        tp.init(fmc);
        sr.init(fmc);
        linkDiscovery.init(fmc);
        restApi.startUp(fmc);
        cm.startUp(fmc);
        tp.startUp(fmc);
        sr.startUp(fmc);
        linkDiscovery.startUp(fmc);
    }

    public Controller getController() {
        return controller;
    }

    protected OFStatisticsReply getStatisticsReply(int transactionId,
            int count, boolean moreReplies) {
        OFStatisticsReply sr = new OFStatisticsReply();
        sr.setXid(transactionId);
        sr.setStatisticType(OFStatisticsType.FLOW);
        List<OFStatistics> statistics = new ArrayList<OFStatistics>();
        for (int i = 0; i < count; ++i) {
            statistics.add(new OFFlowStatisticsReply());
        }
        sr.setStatistics(statistics);
        if (moreReplies)
            sr.setFlags((short) 1);
        return sr;
    }
    
    /* Set the mock expectations for sw when sw is passed to addSwitch */
    protected void setupSwitchForAddSwitch(IOFSwitch sw, long dpid) {
        String dpidString = HexString.toHexString(dpid);
                
        expect(sw.getId()).andReturn(dpid).anyTimes();
        expect(sw.getStringId()).andReturn(dpidString).anyTimes();
        
        //Now we don't write to storage these methods aren't called
        //expect(sw.getConnectedSince()).andReturn(new Date());
        //Channel channel = createMock(Channel.class);
        //expect(sw.getChannel()).andReturn(channel);
        //expect(channel.getRemoteAddress()).andReturn(null);

        expect(sw.getCapabilities()).andReturn(0).anyTimes();
        expect(sw.getBuffers()).andReturn(0).anyTimes();
        expect(sw.getTables()).andReturn((byte)0).anyTimes();
        expect(sw.getActions()).andReturn(0).anyTimes();
        expect(sw.getPorts()).andReturn(new ArrayList<OFPhysicalPort>()).anyTimes();
    }
    
    /**
     * Run the controller's main loop so that updates are processed
     */
    protected class ControllerRunThread extends Thread {
        public void run() {
            controller.openFlowPort = 0; // Don't listen
            controller.run();
        }
    }

    /**
     * Verify that a listener that throws an exception halts further
     * execution, and verify that the Commands STOP and CONTINUE are honored.
     * @throws Exception
     */
    @Test
    public void testHandleMessages() throws Exception {
        Controller controller = getController();
        controller.removeOFMessageListeners(OFType.PACKET_IN);

        IOFSwitch sw = createMock(IOFSwitch.class);
        expect(sw.getStringId()).andReturn("00:00:00:00:00:00:00").anyTimes();

        // Build our test packet
        IPacket testPacket = new Ethernet()
        .setSourceMACAddress("00:44:33:22:11:00")
        .setDestinationMACAddress("00:11:22:33:44:55")
        .setEtherType(Ethernet.TYPE_ARP)
        .setPayload(
                new ARP()
                .setHardwareType(ARP.HW_TYPE_ETHERNET)
                .setProtocolType(ARP.PROTO_TYPE_IP)
                .setHardwareAddressLength((byte) 6)
                .setProtocolAddressLength((byte) 4)
                .setOpCode(ARP.OP_REPLY)
                .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:00"))
                .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
                .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
                .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
        byte[] testPacketSerialized = testPacket.serialize();

        // Build the PacketIn        
        OFPacketIn pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
                .setBufferId(-1)
                .setInPort((short) 1)
                .setPacketData(testPacketSerialized)
                .setReason(OFPacketInReason.NO_MATCH)
                .setTotalLength((short) testPacketSerialized.length);

        IOFMessageListener test1 = createMock(IOFMessageListener.class);
        expect(test1.getName()).andReturn("test1").anyTimes();
        expect(test1.isCallbackOrderingPrereq((OFType)anyObject(), (String)anyObject())).andReturn(false).anyTimes();
        expect(test1.isCallbackOrderingPostreq((OFType)anyObject(), (String)anyObject())).andReturn(false).anyTimes();
        expect(test1.receive(eq(sw), eq(pi), isA(FloodlightContext.class))).andThrow(new RuntimeException("This is NOT an error! We are testing exception catching."));
        IOFMessageListener test2 = createMock(IOFMessageListener.class);
        expect(test2.getName()).andReturn("test2").anyTimes();
        expect(test2.isCallbackOrderingPrereq((OFType)anyObject(), (String)anyObject())).andReturn(false).anyTimes();
        expect(test2.isCallbackOrderingPostreq((OFType)anyObject(), (String)anyObject())).andReturn(false).anyTimes();
        // expect no calls to test2.receive() since test1.receive() threw an exception

        replay(test1, test2, sw);
        controller.addOFMessageListener(OFType.PACKET_IN, test1);
        controller.addOFMessageListener(OFType.PACKET_IN, test2);
        try {
            controller.handleMessage(sw, pi, null);
        } catch (RuntimeException e) {
            assertEquals(e.getMessage().startsWith("This is NOT an error!"), true);
        }
        verify(test1, test2, sw);

        // verify STOP works
        reset(test1, test2, sw);
        expect(test1.receive(eq(sw), eq(pi), isA(FloodlightContext.class))).andReturn(Command.STOP);       
        //expect(test1.getId()).andReturn(0).anyTimes();
        expect(sw.getStringId()).andReturn("00:00:00:00:00:00:00").anyTimes();
        replay(test1, test2, sw);
        controller.handleMessage(sw, pi, null);
        verify(test1, test2, sw);
    }

    public class FutureFetcher<E> implements Runnable {
        public E value;
        public Future<E> future;

        public FutureFetcher(Future<E> future) {
            this.future = future;
        }

        @Override
        public void run() {
            try {
                value = future.get();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        /**
         * @return the value
         */
        public E getValue() {
            return value;
        }

        /**
         * @return the future
         */
        public Future<E> getFuture() {
            return future;
        }
    }

    /**
     * 
     * @throws Exception
     */
    @Test
    public void testOFStatisticsFuture() throws Exception {
        // Test for a single stats reply
        IOFSwitch sw = createMock(IOFSwitch.class);
        sw.cancelStatisticsReply(1);
        OFStatisticsFuture sf = new OFStatisticsFuture(tp, sw, 1);

        replay(sw);
        List<OFStatistics> stats;
        FutureFetcher<List<OFStatistics>> ff = new FutureFetcher<List<OFStatistics>>(sf);
        Thread t = new Thread(ff);
        t.start();
        sf.deliverFuture(sw, getStatisticsReply(1, 10, false));

        t.join();
        stats = ff.getValue();
        verify(sw);
        assertEquals(10, stats.size());

        // Test multiple stats replies
        reset(sw);
        sw.cancelStatisticsReply(1);

        sf = new OFStatisticsFuture(tp, sw, 1);

        replay(sw);
        ff = new FutureFetcher<List<OFStatistics>>(sf);
        t = new Thread(ff);
        t.start();
        sf.deliverFuture(sw, getStatisticsReply(1, 10, true));
        sf.deliverFuture(sw, getStatisticsReply(1, 5, false));
        t.join();

        stats = sf.get();
        verify(sw);
        assertEquals(15, stats.size());

        // Test cancellation
        reset(sw);
        sw.cancelStatisticsReply(1);
        sf = new OFStatisticsFuture(tp, sw, 1);

        replay(sw);
        ff = new FutureFetcher<List<OFStatistics>>(sf);
        t = new Thread(ff);
        t.start();
        sf.cancel(true);
        t.join();

        stats = sf.get();
        verify(sw);
        assertEquals(0, stats.size());

        // Test self timeout
        reset(sw);
        sw.cancelStatisticsReply(1);
        sf = new OFStatisticsFuture(tp, sw, 1, 75, TimeUnit.MILLISECONDS);

        replay(sw);
        ff = new FutureFetcher<List<OFStatistics>>(sf);
        t = new Thread(ff);
        t.start();
        t.join(2000);

        stats = sf.get();
        verify(sw);
        assertEquals(0, stats.size());
    }

    @Test
    public void testAddSwitch() throws Exception {
        controller.activeSwitches = new ConcurrentHashMap<Long, IOFSwitch>();

        //OFSwitchImpl oldsw = createMock(OFSwitchImpl.class);
        OFSwitchImpl oldsw = new OFSwitchImpl();
        OFFeaturesReply featuresReply = new OFFeaturesReply();
        featuresReply.setDatapathId(0L);
        featuresReply.setPorts(new ArrayList<OFPhysicalPort>());
        oldsw.setFeaturesReply(featuresReply);
        //expect(oldsw.getId()).andReturn(0L).anyTimes();
        //expect(oldsw.asyncRemoveSwitchLock()).andReturn(rwlock.writeLock()).anyTimes();
        //oldsw.setConnected(false);
        //expect(oldsw.getStringId()).andReturn("00:00:00:00:00:00:00").anyTimes();

        Channel channel = createNiceMock(Channel.class);
        //expect(oldsw.getChannel()).andReturn(channel);
        oldsw.setChannel(channel);
        expect(channel.close()).andReturn(null);

        IOFSwitch newsw = createMock(IOFSwitch.class);
        expect(newsw.getId()).andReturn(0L).anyTimes();
        expect(newsw.getStringId()).andReturn("00:00:00:00:00:00:00").anyTimes();
        //Now we don't write to storage, these methods aren't called
        //expect(newsw.getConnectedSince()).andReturn(new Date());
        //Channel channel2 = createMock(Channel.class);
        //expect(newsw.getChannel()).andReturn(channel2);
        //expect(channel2.getRemoteAddress()).andReturn(null);
        expect(newsw.getPorts()).andReturn(new ArrayList<OFPhysicalPort>());
        expect(newsw.getCapabilities()).andReturn(0).anyTimes();
        expect(newsw.getBuffers()).andReturn(0).anyTimes();
        expect(newsw.getTables()).andReturn((byte)0).anyTimes();
        expect(newsw.getActions()).andReturn(0).anyTimes();
        controller.activeSwitches.put(0L, oldsw);
        replay(newsw, channel);//, channel2);

        controller.addSwitch(newsw);

        verify(newsw, channel);//, channel2);
    }
    
    @Test
    public void testUpdateQueue() throws Exception {
        class DummySwitchListener implements IOFSwitchListener, IOFSwitchPortListener {
            public int nAdded;
            public int nRemoved;
            public int nPortChanged;
            public DummySwitchListener() {
                nAdded = 0;
                nRemoved = 0;
                nPortChanged = 0;
            }
            public synchronized void addedSwitch(IOFSwitch sw) {
                nAdded++;
                notifyAll();
            }
            public synchronized void removedSwitch(IOFSwitch sw) {
                nRemoved++;
                notifyAll();
            }
            public String getName() {
                return "dummy";
            }
            @Override
            public void switchPortChanged(Long switchId) {
                nPortChanged++;
                notifyAll();
            }
			@Override
			public void switchPortAdded(Long switchId, OFPhysicalPort port) {
				// TODO Auto-generated method stub
				
			}
			@Override
			public void switchPortRemoved(Long switchId, OFPhysicalPort port) {
				// TODO Auto-generated method stub
				
			}
        }
        DummySwitchListener switchListener = new DummySwitchListener();
        IOFSwitch sw = createMock(IOFSwitch.class);
        expect(sw.getId()).andReturn(1L).anyTimes();
        expect(sw.getEnabledPorts()).andReturn(null);
        expect(sw.getChannel()).andReturn(null).anyTimes();
        replay(sw);
        ControllerRunThread t = new ControllerRunThread();
        t.start();
        
        controller.addOFSwitchListener(switchListener);
        synchronized(switchListener) {
            controller.updates.put(controller.new SwitchUpdate(sw,
                                      Controller.SwitchUpdateType.ADDED));
            switchListener.wait(500);
            assertTrue("IOFSwitchListener.addedSwitch() was not called", 
                    switchListener.nAdded == 1);
            controller.updates.put(controller.new SwitchUpdate(sw, 
                                      Controller.SwitchUpdateType.REMOVED));
            switchListener.wait(500);
            assertTrue("IOFSwitchListener.removedSwitch() was not called", 
                    switchListener.nRemoved == 1);
            controller.updates.put(controller.new SwitchUpdate(sw, 
                                      Controller.SwitchUpdateType.PORTCHANGED));
            switchListener.wait(500);
            assertTrue("IOFSwitchListener.switchPortChanged() was not called", 
                    switchListener.nPortChanged == 1);
        }
    }

    /**
     * Test notifications for controller node IP changes. This requires
     * synchronization between the main test thread and another thread 
     * that runs Controller's main loop and takes / handles updates. We
     * synchronize with wait(timeout) / notifyAll(). We check for the 
     * expected condition after the wait returns. However, if wait returns
     * due to the timeout (or due to spurious awaking) and the check fails we
     * might just not have waited long enough. Using a long enough timeout
     * mitigates this but we cannot get rid of the fundamental "issue". 
     * 
     * @throws Exception
     */
    /*
    @Test
    public void testControllerNodeIPChanges() throws Exception {
        class DummyHAListener implements IHAListener {
            public Map<String, String> curControllerNodeIPs;
            public Map<String, String> addedControllerNodeIPs;
            public Map<String, String> removedControllerNodeIPs;
            public int nCalled;
            
            public DummyHAListener() {
                this.nCalled = 0;
            }
                
            @Override
            public void roleChanged(Role oldRole, Role newRole) {
                // ignore
            }
    
            @Override
            public synchronized void controllerNodeIPsChanged(
                    Map<String, String> curControllerNodeIPs,
                    Map<String, String> addedControllerNodeIPs,
                    Map<String, String> removedControllerNodeIPs) {
                this.curControllerNodeIPs = curControllerNodeIPs;
                this.addedControllerNodeIPs = addedControllerNodeIPs;
                this.removedControllerNodeIPs = removedControllerNodeIPs;
                this.nCalled++;
                notifyAll();
            }
            
            public void do_assert(int nCalled,
                    Map<String, String> curControllerNodeIPs,
                    Map<String, String> addedControllerNodeIPs,
                    Map<String, String> removedControllerNodeIPs) {
                assertEquals("nCalled is not as expected", nCalled, this.nCalled);
                assertEquals("curControllerNodeIPs is not as expected", 
                        curControllerNodeIPs, this.curControllerNodeIPs);
                assertEquals("addedControllerNodeIPs is not as expected", 
                        addedControllerNodeIPs, this.addedControllerNodeIPs);
                assertEquals("removedControllerNodeIPs is not as expected", 
                        removedControllerNodeIPs, this.removedControllerNodeIPs);
                
            }
        }
        long waitTimeout = 250; // ms
        DummyHAListener listener  = new DummyHAListener();
        HashMap<String,String> expectedCurMap = new HashMap<String, String>();
        HashMap<String,String> expectedAddedMap = new HashMap<String, String>();
        HashMap<String,String> expectedRemovedMap = new HashMap<String, String>();
        
        controller.addHAListener(listener);
        ControllerRunThread t = new ControllerRunThread();
        t.start();
        
        synchronized(listener) {
            // Insert a first entry
            controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME,
                    getFakeControllerIPRow("row1", "c1", "Ethernet", 0, "1.1.1.1"));
            expectedCurMap.clear();
            expectedAddedMap.clear();
            expectedRemovedMap.clear();
            expectedCurMap.put("c1", "1.1.1.1");
            expectedAddedMap.put("c1", "1.1.1.1");
            listener.wait(waitTimeout);
            listener.do_assert(1, expectedCurMap, expectedAddedMap, expectedRemovedMap);
            
            // Add an interface that we want to ignore. 
            controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME,
                    getFakeControllerIPRow("row2", "c1", "Ethernet", 1, "1.1.1.2"));
            listener.wait(waitTimeout); // TODO: do a different check. This call will have to wait for the timeout
            assertTrue("controllerNodeIPsChanged() should not have been called here", 
                    listener.nCalled == 1);

            // Add another entry
            controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME,
                    getFakeControllerIPRow("row3", "c2", "Ethernet", 0, "2.2.2.2"));
            expectedCurMap.clear();
            expectedAddedMap.clear();
            expectedRemovedMap.clear();
            expectedCurMap.put("c1", "1.1.1.1");
            expectedCurMap.put("c2", "2.2.2.2");
            expectedAddedMap.put("c2", "2.2.2.2");
            listener.wait(waitTimeout);
            listener.do_assert(2, expectedCurMap, expectedAddedMap, expectedRemovedMap);


            // Update an entry
            controller.storageSource.updateRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME,
                    "row3", getFakeControllerIPRow("row3", "c2", "Ethernet", 0, "2.2.2.3"));
            expectedCurMap.clear();
            expectedAddedMap.clear();
            expectedRemovedMap.clear();
            expectedCurMap.put("c1", "1.1.1.1");
            expectedCurMap.put("c2", "2.2.2.3");
            expectedAddedMap.put("c2", "2.2.2.3");
            expectedRemovedMap.put("c2", "2.2.2.2");
            listener.wait(waitTimeout);
            listener.do_assert(3, expectedCurMap, expectedAddedMap, expectedRemovedMap);

            // Delete an entry
            controller.storageSource.deleteRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME, 
                    "row3");
            expectedCurMap.clear();
            expectedAddedMap.clear();
            expectedRemovedMap.clear();
            expectedCurMap.put("c1", "1.1.1.1");
            expectedRemovedMap.put("c2", "2.2.2.3");
            listener.wait(waitTimeout);
            listener.do_assert(4, expectedCurMap, expectedAddedMap, expectedRemovedMap);
        }
    }
    */
    
    /*
    @Test
    public void testGetControllerNodeIPs() {
        HashMap<String,String> expectedCurMap = new HashMap<String, String>();
        
        controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME,
                getFakeControllerIPRow("row1", "c1", "Ethernet", 0, "1.1.1.1"));
        controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME,
                getFakeControllerIPRow("row2", "c1", "Ethernet", 1, "1.1.1.2"));
        controller.storageSource.insertRow(Controller.CONTROLLER_INTERFACE_TABLE_NAME,
                getFakeControllerIPRow("row3", "c2", "Ethernet", 0, "2.2.2.2"));
        expectedCurMap.put("c1", "1.1.1.1");
        expectedCurMap.put("c2", "2.2.2.2");    
        assertEquals("expectedControllerNodeIPs is not as expected", 
                expectedCurMap, controller.getControllerNodeIPs());
    }
    */
    
    @Test
    public void testCheckSwitchReady() {
        OFChannelState state = new OFChannelState();
        Controller.OFChannelHandler chdlr = controller.new OFChannelHandler(state);
        chdlr.sw = createMock(OFSwitchImpl.class);
        
        // Wrong current state 
        // Should not go to READY
        state.hsState = OFChannelState.HandshakeState.HELLO;
        state.hasDescription = true;
        state.hasGetConfigReply = true;
        replay(chdlr.sw);  // nothing called on sw
        chdlr.checkSwitchReady();
        verify(chdlr.sw);
        assertSame(OFChannelState.HandshakeState.HELLO, state.hsState);
        reset(chdlr.sw);
        
        // Have only config reply
        state.hsState = OFChannelState.HandshakeState.FEATURES_REPLY;
        state.hasDescription = false;
        state.hasGetConfigReply = true;
        replay(chdlr.sw); 
        chdlr.checkSwitchReady();
        verify(chdlr.sw);
        assertSame(OFChannelState.HandshakeState.FEATURES_REPLY, state.hsState);
        assertTrue(controller.connectedSwitches.isEmpty());
        assertTrue(controller.activeSwitches.isEmpty());
        reset(chdlr.sw);
        
        // Have only desc reply
        state.hsState = OFChannelState.HandshakeState.FEATURES_REPLY;
        state.hasDescription = true;
        state.hasGetConfigReply = false;
        replay(chdlr.sw); 
        chdlr.checkSwitchReady();
        verify(chdlr.sw);
        assertSame(OFChannelState.HandshakeState.FEATURES_REPLY, state.hsState);
        assertTrue(controller.connectedSwitches.isEmpty());
        assertTrue(controller.activeSwitches.isEmpty());
        reset(chdlr.sw);
        
        //////////////////////////////////////////
        // Finally, everything is right. Should advance to READY
        //////////////////////////////////////////
        controller.roleChanger = createMock(RoleChanger.class);
        state.hsState = OFChannelState.HandshakeState.FEATURES_REPLY;
        state.hasDescription = true;
        state.hasGetConfigReply = true;
        // Role support disabled. Switch should be promoted to active switch
        // list. 
// FIXME: ONOS modified the behavior to always submit Role Request to trigger OFS error.
//        setupSwitchForAddSwitch(chdlr.sw, 0L);
//        chdlr.sw.clearAllFlowMods();
//        replay(controller.roleChanger, chdlr.sw);
//        chdlr.checkSwitchReady();
//        verify(controller.roleChanger, chdlr.sw);
//        assertSame(OFChannelState.HandshakeState.READY, state.hsState);
//        assertSame(chdlr.sw, controller.activeSwitches.get(0L));
//        assertTrue(controller.connectedSwitches.contains(chdlr.sw));
//        assertTrue(state.firstRoleReplyReceived);
        reset(chdlr.sw);
        reset(controller.roleChanger);
        controller.connectedSwitches.clear();
        controller.activeSwitches.clear();
        
        
        // Role support enabled. 
        state.hsState = OFChannelState.HandshakeState.FEATURES_REPLY;
        controller.role = Role.MASTER;
        expect(chdlr.sw.getStringId()).andReturn("SomeID").anyTimes();
        expect(chdlr.sw.getId()).andReturn(42L).anyTimes();
        Capture<Collection<OFSwitchImpl>> swListCapture = 
                    new Capture<Collection<OFSwitchImpl>>();
        controller.roleChanger.submitRequest(capture(swListCapture), 
                    same(Role.SLAVE));
        Capture<Collection<OFSwitchImpl>> swListCapture2 = 
                new Capture<Collection<OFSwitchImpl>>();
        controller.roleChanger.submitRequest(capture(swListCapture2), 
                    same(Role.MASTER));
        replay(controller.roleChanger, chdlr.sw);
        chdlr.checkSwitchReady();
        verify(controller.roleChanger, chdlr.sw);
        assertSame(OFChannelState.HandshakeState.READY, state.hsState);
        assertTrue(controller.activeSwitches.isEmpty());
        assertTrue(controller.connectedSwitches.contains(chdlr.sw));
//        assertTrue(state.firstRoleReplyReceived);
        Collection<OFSwitchImpl> swList = swListCapture.getValue();
        assertEquals(1, swList.size());
        assertTrue("swList must contain this switch", swList.contains(chdlr.sw));
    }

    
    @Test
    public void testChannelDisconnected() throws Exception {
        OFChannelState state = new OFChannelState();
        state.hsState = OFChannelState.HandshakeState.READY;
        Controller.OFChannelHandler chdlr = controller.new OFChannelHandler(state);
        chdlr.sw = createMock(OFSwitchImpl.class);
        
        // Switch is active 
        expect(chdlr.sw.getId()).andReturn(0L).anyTimes();
        expect(chdlr.sw.getStringId()).andReturn("00:00:00:00:00:00:00:00")
                    .anyTimes();
        chdlr.sw.cancelAllStatisticsReplies();
        chdlr.sw.setConnected(false);
        expect(chdlr.sw.isConnected()).andReturn(true);
        
        controller.connectedSwitches.add(chdlr.sw);
        controller.activeSwitches.put(0L, chdlr.sw);
        
        replay(chdlr.sw);
        chdlr.channelDisconnected(null, null);
        verify(chdlr.sw);
        
        // Switch is connected but not active
        reset(chdlr.sw);
        expect(chdlr.sw.getId()).andReturn(0L).anyTimes();
        chdlr.sw.setConnected(false);
        replay(chdlr.sw);
        chdlr.channelDisconnected(null, null);
        verify(chdlr.sw);
        
        // Not in ready state
        state.hsState = HandshakeState.START;
        reset(chdlr.sw);
        replay(chdlr.sw);
        chdlr.channelDisconnected(null, null);
        verify(chdlr.sw);
        
        // Switch is null
        state.hsState = HandshakeState.READY;
        chdlr.sw = null;
        chdlr.channelDisconnected(null, null);
    }
    
    /*
    @Test
    public void testRoleChangeForSerialFailoverSwitch() throws Exception {
        OFSwitchImpl newsw = createMock(OFSwitchImpl.class);
        expect(newsw.getId()).andReturn(0L).anyTimes();
        expect(newsw.getStringId()).andReturn("00:00:00:00:00:00:00").anyTimes();
        Channel channel2 = createMock(Channel.class);
        expect(newsw.getChannel()).andReturn(channel2);
        
        // newsw.role is null because the switch does not support
        // role request messages
        expect(newsw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
                        .andReturn(false);
        // switch is connected 
        controller.connectedSwitches.add(newsw);

        // the switch should get disconnected when role is changed to SLAVE
        expect(channel2.close()).andReturn(null);

        replay(newsw, channel2);
        controller.setRole(Role.SLAVE);
        verify(newsw,  channel2);
    }
    */

    @Test
    public void testRoleNotSupportedError() throws Exception {
        int xid = 424242;
        OFChannelState state = new OFChannelState();
        state.hsState = HandshakeState.READY;
        Controller.OFChannelHandler chdlr = controller.new OFChannelHandler(state);
        chdlr.sw = createMock(OFSwitchImpl.class);
        Channel ch = createMock(Channel.class);
        
        // the error returned when role request message is not supported by sw
        OFError msg = new OFError();
        msg.setType(OFType.ERROR);
        msg.setXid(xid);
        msg.setErrorType(OFErrorType.OFPET_BAD_REQUEST);
        msg.setErrorCode(OFBadRequestCode.OFPBRC_BAD_VENDOR);
        
        // the switch connection should get disconnected when the controller is
        // in SLAVE mode and the switch does not support role-request messages
        state.firstRoleReplyReceived = false;
        controller.role = Role.SLAVE;
        expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true);
        expect(chdlr.sw.deliverRoleRequestNotSupportedEx(xid)).andReturn(Role.SLAVE);
        expect(chdlr.sw.getChannel()).andReturn(ch).anyTimes();
        expect(ch.close()).andReturn(null);
        
        replay(ch, chdlr.sw);
        chdlr.processOFMessage(msg);
        verify(ch, chdlr.sw);
        assertTrue("state.firstRoleReplyReceived must be true", 
                   state.firstRoleReplyReceived);
        assertTrue("activeSwitches must be empty",
                   controller.activeSwitches.isEmpty());
        reset(ch, chdlr.sw);
              
        
        // a different error message - should also reject role request
        msg.setErrorType(OFErrorType.OFPET_BAD_REQUEST);
        msg.setErrorCode(OFBadRequestCode.OFPBRC_EPERM);
        state.firstRoleReplyReceived = false;
        controller.role = Role.SLAVE;
        expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true);
        expect(chdlr.sw.deliverRoleRequestNotSupportedEx(xid)).andReturn(Role.SLAVE);
        expect(chdlr.sw.getChannel()).andReturn(ch).anyTimes();
        expect(ch.close()).andReturn(null);
        replay(ch, chdlr.sw);
        
        chdlr.processOFMessage(msg);
        verify(ch, chdlr.sw);
        assertTrue("state.firstRoleReplyReceived must be True even with EPERM",
                   state.firstRoleReplyReceived);
        assertTrue("activeSwitches must be empty", 
                   controller.activeSwitches.isEmpty());
        reset(ch, chdlr.sw);
    
        
        // We are MASTER, the switch should be added to the list of active
        // switches.
        state.firstRoleReplyReceived = false;
        controller.role = Role.MASTER;
        expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true);
        expect(chdlr.sw.deliverRoleRequestNotSupportedEx(xid)).andReturn(Role.MASTER);
        setupSwitchForAddSwitch(chdlr.sw, 0L);
        chdlr.sw.clearAllFlowMods();
        replay(ch, chdlr.sw);
        
        chdlr.processOFMessage(msg);
        verify(ch, chdlr.sw);
        assertTrue("state.firstRoleReplyReceived must be true", 
                   state.firstRoleReplyReceived);
        assertSame("activeSwitches must contain this switch",
                   chdlr.sw, controller.activeSwitches.get(0L));
        reset(ch, chdlr.sw);

    }
    
    
    @Test 
    public void testVendorMessageUnknown() throws Exception {
        // Check behavior with an unknown vendor id
        OFChannelState state = new OFChannelState();
        state.hsState = HandshakeState.READY;
        Controller.OFChannelHandler chdlr = controller.new OFChannelHandler(state);
        OFVendor msg = new OFVendor();
        msg.setVendor(0);
        chdlr.processOFMessage(msg);
    }
    
    
    // Helper function.
    protected Controller.OFChannelHandler getChannelHandlerForRoleReplyTest() {
        OFChannelState state = new OFChannelState();
        state.hsState = HandshakeState.READY;
        Controller.OFChannelHandler chdlr = controller.new OFChannelHandler(state);
        chdlr.sw = createMock(OFSwitchImpl.class);
        return chdlr;
    }
    
    // Helper function
    protected OFVendor getRoleReplyMsgForRoleReplyTest(int xid, int nicira_role) {
        OFVendor msg = new OFVendor();
        msg.setXid(xid);
        msg.setVendor(OFNiciraVendorData.NX_VENDOR_ID);
        OFRoleReplyVendorData roleReplyVendorData = 
                new OFRoleReplyVendorData(OFRoleReplyVendorData.NXT_ROLE_REPLY);
        msg.setVendorData(roleReplyVendorData);
        roleReplyVendorData.setRole(nicira_role);
        return msg;
    }
   
    /** invalid role in role reply */
    @Test 
    public void testNiciraRoleReplyInvalidRole() 
                    throws Exception {
        int xid = 424242;
        Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
        Channel ch = createMock(Channel.class);
        expect(chdlr.sw.getChannel()).andReturn(ch);
        expect(ch.close()).andReturn(null);
        OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, 232323);
        replay(chdlr.sw, ch);
        chdlr.processOFMessage(msg);
        verify(chdlr.sw, ch);
    }
    
    /** First role reply message received: transition from slave to master */
    @Test 
    public void testNiciraRoleReplySlave2MasterFristTime() 
                    throws Exception {
        int xid = 424242;
        Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
        OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid,
                                       OFRoleReplyVendorData.NX_ROLE_MASTER);
        
        chdlr.sw.deliverRoleReply(xid, Role.MASTER);
        expect(chdlr.sw.isActive()).andReturn(true);
        setupSwitchForAddSwitch(chdlr.sw, 1L);
        chdlr.sw.clearAllFlowMods();
        chdlr.state.firstRoleReplyReceived = false;
        replay(chdlr.sw);
        chdlr.processOFMessage(msg);
        verify(chdlr.sw);
        assertTrue("state.firstRoleReplyReceived must be true", 
                   chdlr.state.firstRoleReplyReceived);
        assertSame("activeSwitches must contain this switch",
                   chdlr.sw, controller.activeSwitches.get(1L));
    }
    
    
    /** Not first role reply message received: transition from slave to master */
    @Test 
    public void testNiciraRoleReplySlave2MasterNotFristTime() 
                    throws Exception {
        int xid = 424242;
        Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
        OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid,
                                       OFRoleReplyVendorData.NX_ROLE_MASTER);
        
        chdlr.sw.deliverRoleReply(xid, Role.MASTER);
        expect(chdlr.sw.isActive()).andReturn(true);
        setupSwitchForAddSwitch(chdlr.sw, 1L);
        chdlr.state.firstRoleReplyReceived = true;
        // Flow table shouldn't be wipe
        replay(chdlr.sw);
        chdlr.processOFMessage(msg);
        verify(chdlr.sw);
        assertTrue("state.firstRoleReplyReceived must be true", 
                   chdlr.state.firstRoleReplyReceived);
        assertSame("activeSwitches must contain this switch",
                   chdlr.sw, controller.activeSwitches.get(1L));
    }
    
    /** transition from slave to equal */
    @Test 
    public void testNiciraRoleReplySlave2Equal() 
                    throws Exception {
        int xid = 424242;
        Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
        OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid,
                                       OFRoleReplyVendorData.NX_ROLE_OTHER);
        
        chdlr.sw.deliverRoleReply(xid, Role.EQUAL);
        expect(chdlr.sw.isActive()).andReturn(true);
        setupSwitchForAddSwitch(chdlr.sw, 1L);
        chdlr.sw.clearAllFlowMods();
        chdlr.state.firstRoleReplyReceived = false;
        replay(chdlr.sw);
        chdlr.processOFMessage(msg);
        verify(chdlr.sw);
        assertTrue("state.firstRoleReplyReceived must be true", 
                   chdlr.state.firstRoleReplyReceived);
        assertSame("activeSwitches must contain this switch",
                   chdlr.sw, controller.activeSwitches.get(1L));
    };
    
    @Test
    /** Slave2Slave transition ==> no change */
    public void testNiciraRoleReplySlave2Slave() throws Exception{
        int xid = 424242;
        Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
        OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, 
                                       OFRoleReplyVendorData.NX_ROLE_SLAVE);
        
        chdlr.sw.deliverRoleReply(xid, Role.SLAVE);
        expect(chdlr.sw.getId()).andReturn(1L).anyTimes();
        expect(chdlr.sw.getStringId()).andReturn("00:00:00:00:00:00:00:01")
                    .anyTimes();
        expect(chdlr.sw.isActive()).andReturn(false);
        // don't add switch to activeSwitches ==> slave2slave
        chdlr.state.firstRoleReplyReceived = false;
        replay(chdlr.sw);
        chdlr.processOFMessage(msg);
        verify(chdlr.sw);
        assertTrue("state.firstRoleReplyReceived must be true", 
                   chdlr.state.firstRoleReplyReceived);
        assertTrue("activeSwitches must be empty", 
                   controller.activeSwitches.isEmpty());
    }
    
    @Test
    /** Equal2Master transition ==> no change */
    public void testNiciraRoleReplyEqual2Master() throws Exception{
        int xid = 424242;
        Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
        OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, 
                                       OFRoleReplyVendorData.NX_ROLE_MASTER);
        
        chdlr.sw.deliverRoleReply(xid, Role.MASTER);
        expect(chdlr.sw.getId()).andReturn(1L).anyTimes();
        expect(chdlr.sw.getStringId()).andReturn("00:00:00:00:00:00:00:01")
                    .anyTimes();
        expect(chdlr.sw.isActive()).andReturn(true);
        controller.activeSwitches.put(1L, chdlr.sw);
        chdlr.state.firstRoleReplyReceived = false;
        replay(chdlr.sw);
        chdlr.processOFMessage(msg);
        verify(chdlr.sw);
        assertTrue("state.firstRoleReplyReceived must be true", 
                   chdlr.state.firstRoleReplyReceived);
        assertSame("activeSwitches must contain this switch",
                   chdlr.sw, controller.activeSwitches.get(1L));
    }
    
    @Test 
    public void testNiciraRoleReplyMaster2Slave() 
                    throws Exception {
        int xid = 424242;
        Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
        OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, 
                                       OFRoleReplyVendorData.NX_ROLE_SLAVE);
        
        chdlr.sw.deliverRoleReply(xid, Role.SLAVE);
        expect(chdlr.sw.getId()).andReturn(1L).anyTimes();
        expect(chdlr.sw.getStringId()).andReturn("00:00:00:00:00:00:00:01")
                    .anyTimes();
        controller.activeSwitches.put(1L, chdlr.sw);
        expect(chdlr.sw.isActive()).andReturn(false);
        expect(chdlr.sw.isConnected()).andReturn(true);
        chdlr.sw.cancelAllStatisticsReplies();
        chdlr.state.firstRoleReplyReceived = false;
        replay(chdlr.sw);
        chdlr.processOFMessage(msg);
        verify(chdlr.sw);
        assertTrue("state.firstRoleReplyReceived must be true", 
                   chdlr.state.firstRoleReplyReceived);
        assertTrue("activeSwitches must be empty", 
                   controller.activeSwitches.isEmpty());
    }
    
    /**
     * Tests that you can't remove a switch from the active
     * switch list.
     * @throws Exception
     */
    @Test
    public void testRemoveActiveSwitch() {
        IOFSwitch sw = EasyMock.createNiceMock(IOFSwitch.class);
        boolean exceptionThrown = false;
        expect(sw.getId()).andReturn(1L).anyTimes();
        replay(sw);
        getController().activeSwitches.put(sw.getId(), sw);
        try {
            getController().getSwitches().remove(1L);
        } catch (UnsupportedOperationException e) {
            exceptionThrown = true;
        }
        assertTrue(exceptionThrown);
        verify(sw);
    }
    
    public void verifyPortChangedUpdateInQueue(IOFSwitch sw) throws Exception {
        assertEquals(1, controller.updates.size());
        IUpdate update = controller.updates.take();
        assertEquals(true, update instanceof SwitchUpdate);
        SwitchUpdate swUpdate = (SwitchUpdate)update;
        assertEquals(sw, swUpdate.sw);
        assertEquals(SwitchUpdateType.PORTCHANGED, swUpdate.switchUpdateType);
    }
    
    public void verifyPortAddedUpdateInQueue(IOFSwitch sw) throws Exception {
        assertEquals(2, controller.updates.size());
        IUpdate update = controller.updates.take();
        assertEquals(true, update instanceof SwitchUpdate);
        SwitchUpdate swUpdate = (SwitchUpdate)update;
        assertEquals(sw, swUpdate.sw);
        assertEquals(SwitchUpdateType.PORTADDED, swUpdate.switchUpdateType);
        verifyPortChangedUpdateInQueue(sw);
    }
    
    public void verifyPortRemovedUpdateInQueue(IOFSwitch sw) throws Exception {
        assertEquals(2, controller.updates.size());
        IUpdate update = controller.updates.take();
        assertEquals(true, update instanceof SwitchUpdate);
        SwitchUpdate swUpdate = (SwitchUpdate)update;
        assertEquals(sw, swUpdate.sw);
        assertEquals(SwitchUpdateType.PORTREMOVED, swUpdate.switchUpdateType);
        verifyPortChangedUpdateInQueue(sw);
    }
    
    /*
     * Test handlePortStatus()
     * TODO: test correct updateStorage behavior!
     */
    @Test 
    public void testHandlePortStatus() throws Exception {
        IOFSwitch sw = createMock(IOFSwitch.class);
        expect(sw.getId()).andReturn(1L).anyTimes();
        OFPhysicalPort port = new OFPhysicalPort();
        port.setName("myPortName1");
        port.setPortNumber((short)42);
        
        OFPortStatus ofps = new OFPortStatus();
        ofps.setDesc(port);
        
        ofps.setReason((byte)OFPortReason.OFPPR_ADD.ordinal());
        sw.setPort(port);
        expectLastCall().once();
        replay(sw);
        controller.handlePortStatusMessage(sw, ofps, false);
        verify(sw);
        verifyPortAddedUpdateInQueue(sw);
        reset(sw);
        
        // ONOS:Port is considered added if Link state is not down and not configured to be down
        ofps.setReason((byte)OFPortReason.OFPPR_MODIFY.ordinal());
        sw.setPort(port);
        expectLastCall().once();
        replay(sw);
        controller.handlePortStatusMessage(sw, ofps, false);
        verify(sw);
        verifyPortAddedUpdateInQueue(sw);
        reset(sw);
        
        // ONOS:Port is considered removed if Link state is down
        ofps.setReason((byte)OFPortReason.OFPPR_MODIFY.ordinal());
        port.setState(OFPortState.OFPPS_LINK_DOWN.getValue());
        sw.setPort(port);
        expectLastCall().once();
        replay(sw);
        controller.handlePortStatusMessage(sw, ofps, false);
        verify(sw);
        verifyPortRemovedUpdateInQueue(sw);
        reset(sw);
        port.setState(0);// reset
        
        // ONOS: .. or is configured to be down
        ofps.setReason((byte)OFPortReason.OFPPR_MODIFY.ordinal());
        port.setConfig(OFPortConfig.OFPPC_PORT_DOWN.getValue());
        sw.setPort(port);
        expectLastCall().once();
        replay(sw);
        controller.handlePortStatusMessage(sw, ofps, false);
        verify(sw);
        verifyPortRemovedUpdateInQueue(sw);
        reset(sw);
        port.setConfig(0);// reset
        
        
        ofps.setReason((byte)OFPortReason.OFPPR_DELETE.ordinal());
        sw.deletePort(port.getPortNumber());
        expectLastCall().once();
        replay(sw);
        controller.handlePortStatusMessage(sw, ofps, false);
        verify(sw);
        verifyPortRemovedUpdateInQueue(sw);
        reset(sw);
    }
}
