/**
 *    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.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);
    }
}
