package net.floodlightcontroller.core.internal;

import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.List;

import net.floodlightcontroller.core.IFloodlightProviderService.Role;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.internal.OFSwitchImpl.PendingRoleRequestEntry;
import net.floodlightcontroller.core.test.MockFloodlightProvider;
import net.floodlightcontroller.test.FloodlightTestCase;

import org.easymock.Capture;
import org.jboss.netty.channel.Channel;
import org.junit.Before;
import org.junit.Test;
import org.openflow.protocol.OFMessage;
import org.openflow.protocol.OFType;
import org.openflow.protocol.OFVendor;
import org.openflow.protocol.vendor.OFVendorData;
import org.openflow.vendor.nicira.OFNiciraVendorData;
import org.openflow.vendor.nicira.OFRoleRequestVendorData;
import org.openflow.vendor.nicira.OFRoleVendorData;

public class OFSwitchImplTest extends FloodlightTestCase {
    protected OFSwitchImpl sw;
    
    
    @Before
    public void setUp() throws Exception {
        sw = new OFSwitchImpl();
        Channel ch = createMock(Channel.class);
        SocketAddress sa = new InetSocketAddress(42);
        expect(ch.getRemoteAddress()).andReturn(sa).anyTimes();
        sw.setChannel(ch);
        MockFloodlightProvider floodlightProvider = new MockFloodlightProvider();
        sw.setFloodlightProvider(floodlightProvider);
    }

    
    public void doSendNxRoleRequest(Role role, int nx_role) throws Exception {
        long cookie = System.nanoTime();
        
        // verify that the correct OFMessage is sent
        Capture<List<OFMessage>> msgCapture = new Capture<List<OFMessage>>();
        expect(sw.channel.write(capture(msgCapture))).andReturn(null);
        replay(sw.channel);
        int xid = sw.sendNxRoleRequest(role, cookie);
        verify(sw.channel);
        List<OFMessage> msgList = msgCapture.getValue();
        assertEquals(1, msgList.size());
        OFMessage msg = msgList.get(0);
        assertEquals("Transaction Ids must match", xid, msg.getXid()); 
        assertTrue("Message must be an OFVendor type", msg instanceof OFVendor);
        assertEquals(OFType.VENDOR, msg.getType());
        OFVendor vendorMsg = (OFVendor)msg;
        assertEquals("Vendor message must be vendor Nicira",
                     OFNiciraVendorData.NX_VENDOR_ID, vendorMsg.getVendor());
        OFVendorData vendorData = vendorMsg.getVendorData();
        assertTrue("Vendor Data must be an OFRoleRequestVendorData",
                     vendorData instanceof OFRoleRequestVendorData);
        OFRoleRequestVendorData roleRequest = (OFRoleRequestVendorData)vendorData;
        assertEquals(nx_role, roleRequest.getRole());
        
        // Now verify that we've added the pending request correctly
        // to the pending queue
        assertEquals(1, sw.pendingRoleRequests.size());
        PendingRoleRequestEntry pendingRoleRequest = sw.pendingRoleRequests.poll();
        assertEquals(msg.getXid(), pendingRoleRequest.xid);
        assertEquals(role, pendingRoleRequest.role);
        assertEquals(cookie, pendingRoleRequest.cookie);
        reset(sw.channel);
    }
    
    @Test
    public void testSendNxRoleRequest() throws Exception {
        doSendNxRoleRequest(Role.MASTER, OFRoleVendorData.NX_ROLE_MASTER);
        doSendNxRoleRequest(Role.SLAVE, OFRoleVendorData.NX_ROLE_SLAVE);
        doSendNxRoleRequest(Role.EQUAL, OFRoleVendorData.NX_ROLE_OTHER);
    }
    
    
    @Test
    public void testDeliverRoleReplyOk() {
        // test normal case
        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
                            (int)System.currentTimeMillis(),  // arbitrary xid
                            Role.MASTER,
                            System.nanoTime() // arbitrary cookie
                            );
        sw.pendingRoleRequests.add(pending);
        replay(sw.channel);
        sw.deliverRoleReply(pending.xid, pending.role);
        verify(sw.channel);
        assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
        assertEquals(pending.role, sw.role);
        assertEquals(0, sw.pendingRoleRequests.size());
    }
    
    @Test
    public void testDeliverRoleReplyOkRepeated() {
        // test normal case. Not the first role reply
        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
                            (int)System.currentTimeMillis(),  // arbitrary xid
                            Role.MASTER,
                            System.nanoTime() // arbitrary cookie
                            );
        sw.setAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE, true);
        sw.pendingRoleRequests.add(pending);
        replay(sw.channel);
        sw.deliverRoleReply(pending.xid, pending.role);
        verify(sw.channel);
        assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
        assertEquals(pending.role, sw.role);
        assertEquals(0, sw.pendingRoleRequests.size());
    }
    
    @Test
    public void testDeliverRoleReplyNonePending() {
        // nothing pending 
        expect(sw.channel.close()).andReturn(null);
        replay(sw.channel);
        sw.deliverRoleReply(1, Role.MASTER);
        verify(sw.channel);
        assertEquals(0, sw.pendingRoleRequests.size());
    }
    
    @Test
    public void testDeliverRoleReplyWrongXid() {
        // wrong xid received 
        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
                            (int)System.currentTimeMillis(),  // arbitrary xid
                            Role.MASTER,
                            System.nanoTime() // arbitrary cookie
                            );
        sw.pendingRoleRequests.add(pending);
        expect(sw.channel.close()).andReturn(null);
        replay(sw.channel);
        sw.deliverRoleReply(pending.xid+1, pending.role);
        verify(sw.channel);
        assertEquals(null, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
        assertEquals(0, sw.pendingRoleRequests.size());
    }
    
    @Test
    public void testDeliverRoleReplyWrongRole() {
        // correct xid but incorrect role received
        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
                            (int)System.currentTimeMillis(),  // arbitrary xid
                            Role.MASTER,
                            System.nanoTime() // arbitrary cookie
                            );
        sw.pendingRoleRequests.add(pending);
        expect(sw.channel.close()).andReturn(null);
        replay(sw.channel);
        sw.deliverRoleReply(pending.xid, Role.SLAVE);
        verify(sw.channel);
        assertEquals(null, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
        assertEquals(0, sw.pendingRoleRequests.size());
    }
    
    @Test
    public void testCheckFirstPendingRoleRequestXid() {
        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
                            54321, Role.MASTER, 232323);
        replay(sw.channel); // we don't expect any invocations 
        sw.pendingRoleRequests.add(pending);
        assertEquals(true, sw.checkFirstPendingRoleRequestXid(54321));
        assertEquals(false, sw.checkFirstPendingRoleRequestXid(0));
        sw.pendingRoleRequests.clear();
        assertEquals(false, sw.checkFirstPendingRoleRequestXid(54321));
        verify(sw.channel);
    }
    
    @Test
    public void testCheckFirstPendingRoleRequestCookie() {
        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
                            54321, Role.MASTER, 232323);
        replay(sw.channel); // we don't expect any invocations 
        sw.pendingRoleRequests.add(pending);
        assertEquals(true, sw.checkFirstPendingRoleRequestCookie(232323));
        assertEquals(false, sw.checkFirstPendingRoleRequestCookie(0));
        sw.pendingRoleRequests.clear();
        assertEquals(false, sw.checkFirstPendingRoleRequestCookie(232323));
        verify(sw.channel);
    }
    
    @Test
    public void testDeliverRoleRequestNotSupported () {
        // normal case. xid is pending 
        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
                            (int)System.currentTimeMillis(),  // arbitrary xid
                            Role.MASTER,
                            System.nanoTime() // arbitrary cookie
                            );
        sw.role = Role.SLAVE;
        sw.pendingRoleRequests.add(pending);
        replay(sw.channel);
        sw.deliverRoleRequestNotSupportedEx(pending.xid);
        verify(sw.channel);
        assertEquals(false, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
        assertEquals(null, sw.role);
        assertEquals(0, sw.pendingRoleRequests.size());
    }
    
    @Test
    public void testDeliverRoleRequestNotSupportedNonePending() {
        // nothing pending 
        sw.role = Role.SLAVE;
        expect(sw.channel.close()).andReturn(null);
        replay(sw.channel);
        sw.deliverRoleRequestNotSupportedEx(1);
        verify(sw.channel);
        assertEquals(null, sw.role);
        assertEquals(0, sw.pendingRoleRequests.size());
    }
    
    @Test
    public void testDeliverRoleRequestNotSupportedWrongXid() {
        // wrong xid received 
        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
                            (int)System.currentTimeMillis(),  // arbitrary xid
                            Role.MASTER,
                            System.nanoTime() // arbitrary cookie
                            );
        sw.role = Role.SLAVE;
        sw.pendingRoleRequests.add(pending);
        expect(sw.channel.close()).andReturn(null);
        replay(sw.channel);
        sw.deliverRoleRequestNotSupportedEx(pending.xid+1);
        verify(sw.channel);
        assertEquals(null, sw.role);
        assertEquals(0, sw.pendingRoleRequests.size());
    }
}
