package net.floodlightcontroller.core.internal;

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

import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;

import net.floodlightcontroller.core.IFloodlightProviderService.Role;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.internal.RoleChanger.RoleChangeTask;

import org.easymock.EasyMock;
import org.jboss.netty.channel.Channel;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

public class RoleChangerTest {
    public RoleChanger roleChanger;

    @Before
    public void setUp() throws Exception {
        roleChanger = new RoleChanger();
    }

    /**
     * Send a role request for SLAVE to a switch that doesn't support it.
     * The connection should be closed.
     */
    @Test
    public void testSendRoleRequestSlaveNotSupported() {
        LinkedList<OFSwitchImpl> switches = new LinkedList<OFSwitchImpl>();

        // a switch that doesn't support role requests
        OFSwitchImpl sw1 = EasyMock.createMock(OFSwitchImpl.class);
        Channel channel1 = createMock(Channel.class);
        expect(sw1.getChannel()).andReturn(channel1);
        // No support for NX_ROLE
        expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
                .andReturn(false);
        expect(channel1.close()).andReturn(null);
        switches.add(sw1);

        replay(sw1, channel1);
        roleChanger.sendRoleRequest(switches, Role.SLAVE, 123456);
        verify(sw1, channel1);

        // sendRoleRequest needs to remove the switch from the list since
        // it closed its connection
        assertTrue(switches.isEmpty());
    }

    /**
     * Send a role request for MASTER to a switch that doesn't support it.
     * The connection should be closed.
     */
    @Test
    @Ignore
    // FIXME: ONOS modified the behavior here to intentionally trigger OFS error.
    public void testSendRoleRequestMasterNotSupported() {
        LinkedList<OFSwitchImpl> switches = new LinkedList<OFSwitchImpl>();

        // a switch that doesn't support role requests
        OFSwitchImpl sw1 = EasyMock.createMock(OFSwitchImpl.class);
        // No support for NX_ROLE
        expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
                .andReturn(false);
        switches.add(sw1);

        replay(sw1);
        roleChanger.sendRoleRequest(switches, Role.MASTER, 123456);
        verify(sw1);

        assertEquals(1, switches.size());
    }

    /**
     * Send a role request a switch that supports it and one that
     * hasn't had a role request send to it yet
     */
    @Test
    public void testSendRoleRequestErrorHandling() throws Exception {
        LinkedList<OFSwitchImpl> switches = new LinkedList<OFSwitchImpl>();

        // a switch that supports role requests
        OFSwitchImpl sw1 = EasyMock.createMock(OFSwitchImpl.class);
        // No support for NX_ROLE
        expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
                .andReturn(true);
        expect(sw1.sendNxRoleRequest(Role.MASTER, 123456))
                .andThrow(new IOException()).once();
        Channel channel1 = createMock(Channel.class);
        expect(sw1.getChannel()).andReturn(channel1);
        expect(channel1.close()).andReturn(null);
        switches.add(sw1);

        replay(sw1);
        roleChanger.sendRoleRequest(switches, Role.MASTER, 123456);
        verify(sw1);

        assertTrue(switches.isEmpty());
    }

    /**
     * Check error handling
     * hasn't had a role request send to it yet
     */
    @Test
    public void testSendRoleRequestSupported() throws Exception {
        LinkedList<OFSwitchImpl> switches = new LinkedList<OFSwitchImpl>();

        // a switch that supports role requests
        OFSwitchImpl sw1 = EasyMock.createMock(OFSwitchImpl.class);
        // No support for NX_ROLE
        expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
                .andReturn(true);
        expect(sw1.sendNxRoleRequest(Role.MASTER, 123456)).andReturn(1).once();
        switches.add(sw1);

        // a switch for which we don't have SUPPORTS_NX_ROLE yet
        OFSwitchImpl sw2 = EasyMock.createMock(OFSwitchImpl.class);
        // No support for NX_ROLE
        expect(sw2.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
                .andReturn(null);
        expect(sw2.sendNxRoleRequest(Role.MASTER, 123456)).andReturn(1).once();
        switches.add(sw2);


        replay(sw1, sw2);
        roleChanger.sendRoleRequest(switches, Role.MASTER, 123456);
        verify(sw1, sw2);

        assertEquals(2, switches.size());
    }

    @Test
    public void testVerifyRoleReplyReceived() {
        LinkedList<OFSwitchImpl> switches = new LinkedList<OFSwitchImpl>();

        // Add a switch that has received a role reply
        OFSwitchImpl sw1 = EasyMock.createMock(OFSwitchImpl.class);
        expect(sw1.checkFirstPendingRoleRequestCookie(123456))
                .andReturn(false).once();
        switches.add(sw1);

        // Add a switch that has not yet received a role reply
        OFSwitchImpl sw2 = EasyMock.createMock(OFSwitchImpl.class);
        expect(sw2.checkFirstPendingRoleRequestCookie(123456))
                .andReturn(true).once();
        Channel channel2 = createMock(Channel.class);
        expect(sw2.getChannel()).andReturn(channel2);
        expect(channel2.close()).andReturn(null);
        switches.add(sw2);


        replay(sw1, sw2);
        roleChanger.verifyRoleReplyReceived(switches, 123456);
        verify(sw1, sw2);

        assertEquals(2, switches.size());
    }

    @Test
    public void testRoleChangeTask() {
        @SuppressWarnings("unchecked")
        Collection<OFSwitchImpl> switches =
                EasyMock.createMock(Collection.class);
        long now = System.nanoTime();
        long dt1 = 10 * 1000 * 1000 * 1000L;
        long dt2 = 20 * 1000 * 1000 * 1000L;
        long dt3 = 15 * 1000 * 1000 * 1000L;
        RoleChangeTask t1 = new RoleChangeTask(switches, null, now + dt1);
        RoleChangeTask t2 = new RoleChangeTask(switches, null, now + dt2);
        RoleChangeTask t3 = new RoleChangeTask(switches, null, now + dt3);

        // FIXME: cannot test comparison against self. grrr
        //assertTrue( t1.compareTo(t1) <= 0 );
        assertTrue(t1.compareTo(t2) < 0);
        assertTrue(t1.compareTo(t3) < 0);

        assertTrue(t2.compareTo(t1) > 0);
        //assertTrue( t2.compareTo(t2) <= 0 );
        assertTrue(t2.compareTo(t3) > 0);
    }

    @Test
    public void testSubmitRequest() throws Exception {
        LinkedList<OFSwitchImpl> switches = new LinkedList<OFSwitchImpl>();
        roleChanger.timeout = 500 * 1000 * 1000; // 500 ms

        // a switch that supports role requests
        OFSwitchImpl sw1 = EasyMock.createStrictMock(OFSwitchImpl.class);
        // No support for NX_ROLE
        expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
                .andReturn(true);
        expect(sw1.sendNxRoleRequest(EasyMock.same(Role.MASTER), EasyMock.anyLong()))
                .andReturn(1);
        expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
                .andReturn(true);
        expect(sw1.sendNxRoleRequest(EasyMock.same(Role.SLAVE), EasyMock.anyLong()))
                .andReturn(1);
        // The following calls happen for timeout handling:
        expect(sw1.checkFirstPendingRoleRequestCookie(EasyMock.anyLong()))
                .andReturn(false);
        expect(sw1.checkFirstPendingRoleRequestCookie(EasyMock.anyLong()))
                .andReturn(false);
        switches.add(sw1);


        replay(sw1);
        roleChanger.submitRequest(switches, Role.MASTER);
        roleChanger.submitRequest(switches, Role.SLAVE);
        // Wait until role request has been sent. 
        // TODO: need to get rid of this sleep somehow
        Thread.sleep(100);
        // Now there should be exactly one timeout task pending
        assertEquals(2, roleChanger.pendingTasks.size());
        // Make sure it's indeed a timeout task
        assertSame(RoleChanger.RoleChangeTask.Type.TIMEOUT,
                roleChanger.pendingTasks.peek().type);
        // Check that RoleChanger indeed made a copy of switches collection
        assertNotSame(switches, roleChanger.pendingTasks.peek().switches);

        // Wait until the timeout triggers 
        // TODO: get rid of this sleep too.
        Thread.sleep(500);
        assertEquals(0, roleChanger.pendingTasks.size());
        verify(sw1);

    }

}
