package net.onrc.onos.core.hostmanager;

import static org.easymock.EasyMock.anyObject;
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.replay;

import java.util.Date;

import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IListener.Command;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.IUpdate;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.test.FloodlightTestCase;
import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.core.datagrid.IDatagridService;
import net.onrc.onos.core.datagrid.IEventChannel;
import net.onrc.onos.core.datagrid.IEventChannelListener;
import net.onrc.onos.core.packet.ARP;
import net.onrc.onos.core.packet.DHCP;
import net.onrc.onos.core.packet.Data;
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.packet.UDP;
import net.onrc.onos.core.registry.IControllerRegistryService;
import net.onrc.onos.core.topology.ITopologyListener;
import net.onrc.onos.core.topology.ITopologyService;
import net.onrc.onos.core.topology.MockTopology;
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.PortNumber;

import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openflow.protocol.OFPacketIn;
import org.openflow.protocol.OFType;

/**
 * Unit tests for the Host Manager module (HostManger).
 * These test cases check the result of add/delete host and
 * verify the result of processPacketIn by injecting fake packets.
 * floodlightProvider, datagridService, topologyService,
 * controllerRegistryService, eventChannel are mocked out.
 */
public class HostManagerTest extends FloodlightTestCase {
    private IPacket pkt0, pkt1, pkt2, pkt3, pkt4;
    private IOFSwitch sw1;
    private long sw1Dpid;
    private long sw1DevPort, sw1DevPort2;
    private HostManager hostManager;
    private OFPacketIn pktIn, pktIn2;
    private FloodlightModuleContext modContext;
    private ITopologyService networkGraphService;
    private IEventChannel<Long, Host> eventChannel;
    private IFloodlightProviderService floodlightProvider;
    private Date lastSeenTimestamp;

    @Override
    @Before
    @SuppressWarnings("unchecked")
    public void setUp() throws Exception {
        super.setUp();
        MockTopology topology = new MockTopology();
        IDatagridService datagridService;
        IControllerRegistryService controllerRegistryService;

        topology.createSampleTopology2();
        modContext = new FloodlightModuleContext();

        floodlightProvider = createMock(IFloodlightProviderService.class);
        datagridService = createMock(IDatagridService.class);
        networkGraphService = createMock(ITopologyService.class);
        controllerRegistryService = createMock(IControllerRegistryService.class);
        eventChannel = createMock(IEventChannel.class);
        expect(networkGraphService.getTopology()).andReturn(topology).anyTimes();
        networkGraphService.registerTopologyListener(anyObject(ITopologyListener.class));
        expectLastCall();

        expect(datagridService.createChannel("onos.host", Long.class, Host.class))
        .andReturn(eventChannel).once();
        expect(topology.getOutgoingLink(new Dpid(1L), new PortNumber((short) 100))).andReturn(null).anyTimes();
        expect(datagridService.addListener(
                eq("onos.host"),
                anyObject(IEventChannelListener.class),
                eq(Long.class),
                eq(Host.class)))
                .andReturn(eventChannel).once();

        replay(datagridService);
        replay(networkGraphService);
        replay(controllerRegistryService);

        modContext.addService(IDatagridService.class, datagridService);
        modContext.addService(ITopologyService.class, networkGraphService);
        modContext.addService(IFloodlightProviderService.class, floodlightProvider);
        modContext.getServiceImpl(IFloodlightProviderService.class);
        sw1Dpid = 1L;
        sw1 = createMockSwitch(sw1Dpid);
        replay(sw1);

        sw1DevPort = 100;
        sw1DevPort2 = 12L;

        hostManager = new HostManager();
        /*
         * Broadcast source address
         */
        this.pkt0 = new Ethernet()
        .setDestinationMACAddress("00:44:33:22:11:33")
        .setSourceMACAddress("FF:FF:FF:FF:FF:FF")
        .setEtherType(Ethernet.TYPE_IPV4)
        .setPayload(
                new IPv4()
                .setTtl((byte) 128)
                .setSourceAddress("192.168.10.1")
                .setDestinationAddress("192.168.255.255")
                .setPayload(new UDP()
                .setSourcePort((short) 5000)
                .setDestinationPort((short) 5001)
                .setPayload(new Data(new byte[]{0x01}))));
        /*
         * Normal IPv4 packet
         */
        this.pkt1 = new Ethernet()
        .setDestinationMACAddress("00:11:22:33:44:55")
        .setSourceMACAddress("00:44:33:22:11:00")
        .setEtherType(Ethernet.TYPE_IPV4)
        .setPayload(
                new IPv4()
                .setTtl((byte) 128)
                .setSourceAddress("192.168.1.1")
                .setDestinationAddress("192.168.1.2")
                .setPayload(new UDP()
                .setSourcePort((short) 5000)
                .setDestinationPort((short) 5001)
                .setPayload(new Data(new byte[]{0x01}))));
        /*
         * Same MAC header as pkt1,but not IP address set
         */
        this.pkt2 = new Ethernet()
        .setSourceMACAddress("00:44:33:22:11:01")
        .setDestinationMACAddress("00:11:22:33:44:55")
        .setEtherType(Ethernet.TYPE_IPV4)
        .setPayload(
                new IPv4()
                .setTtl((byte) 128)
                .setPayload(new UDP()
                .setSourcePort((short) 5000)
                .setDestinationPort((short) 5001)
                .setPayload(new Data(new byte[]{0x01}))));
        /*
         * DHCP packet
         */
        this.pkt3 = new Ethernet()
        .setSourceMACAddress("00:44:33:22:11:01")
        .setDestinationMACAddress("00:11:22:33:44:55")
        .setEtherType(Ethernet.TYPE_IPV4)
        .setPayload(
                new IPv4()
                .setTtl((byte) 128)
                .setSourceAddress("192.168.1.1")
                .setDestinationAddress("192.168.1.2")
                .setPayload(new UDP()
                .setSourcePort((short) 5000)
                .setDestinationPort((short) 5001)
                .setChecksum((short) 0)
                .setPayload(
                        new DHCP()
                        .setOpCode(DHCP.OPCODE_REPLY)
                        .setHardwareType(DHCP.HWTYPE_ETHERNET)
                        .setHardwareAddressLength((byte) 6)
                        .setHops((byte) 0)
                        .setTransactionId(0x00003d1d)
                        .setSeconds((short) 0)
                        .setFlags((short) 0)
                        .setClientIPAddress(0)
                        .setYourIPAddress(0)
                        .setServerIPAddress(0)
                        .setGatewayIPAddress(0))));
        /*
         * ARP packet
         */
        this.pkt4 = new Ethernet()
        .setSourceMACAddress("00:44:33:22:11:01")
        .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:01"))
                .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
                .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
                .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));


        this.pktIn = new OFPacketIn().setInPort((short) sw1DevPort);

        this.pktIn2 = new OFPacketIn().setInPort((short) sw1DevPort2);

        lastSeenTimestamp = new Date(1);
    }

    @Override
    @After
    public void tearDown() throws Exception {
    }

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

    /**
     * Test set operation on lastSeenTimstamp field in Host.
     */
    @Test
    public void testSetLastSeenTimestamp() {
        Ethernet eth = (Ethernet) pkt1;
        Host srcHost = hostManager.getSourceHostFromPacket(eth, sw1Dpid, sw1DevPort);

        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(HostManager.class));
        srcHost.setLastSeenTimestamp(lastSeenTimestamp);
        assertEquals(lastSeenTimestamp, srcHost.getLastSeenTimestamp());
    }
    /**
     * test the functionality to get the source host from Packet header
     * information.
     */
    @Test
    public void testGetSourceHostFromPacket() {
        byte[] address = new byte[] {0x00, 0x44, 0x33, 0x22, 0x11, 0x01};
        MACAddress srcMac = new MACAddress(address);
        Host host1 = new Host(srcMac,
                null,
                sw1Dpid,
                sw1DevPort,
                null);

        /*
         * test DHCP packet case
         */
        Ethernet eth = (Ethernet) pkt3;
        Host host2 = hostManager.getSourceHostFromPacket(eth, sw1Dpid, sw1DevPort);
        assertEquals(host1, host2);

        /*
         * test ARP packet case
         */
        eth = (Ethernet) pkt4;
        host2 = hostManager.getSourceHostFromPacket(eth, sw1Dpid, sw1DevPort);
        assertEquals(host1, host2);
    }

    /**
     * This test will invoke addHost to add a new host through Packet pkt1.
     * @throws FloodlightModuleException
     */
    @Test
    public void testProcessPacketInAddNewHost() throws FloodlightModuleException {
        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN),
                EasyMock.isA(HostManager.class));
        EasyMock.expectLastCall();
        floodlightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
        EasyMock.expectLastCall();
        replay(floodlightProvider);

        hostManager.init(modContext);
        hostManager.startUp(modContext);
        Command cmd = hostManager.processPacketIn(sw1, pktIn, (Ethernet) pkt1);
        assertEquals(Command.CONTINUE, cmd);

        EasyMock.verify(floodlightProvider);
    }

    /**
     * Test ProcessPacket function.
     * @throws FloodlightModuleException
     */
    @Test
    public void testProcessPacketInHasLink() throws FloodlightModuleException {
        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN),
                EasyMock.isA(HostManager.class));
        EasyMock.expectLastCall();
        replay(floodlightProvider);

        hostManager.init(modContext);
        hostManager.startUp(modContext);
        Command cmd = hostManager.processPacketIn(sw1, pktIn2, (Ethernet) pkt1);
        assertEquals(Command.CONTINUE, cmd);

        EasyMock.verify(floodlightProvider);
    }

    /**
     * Test return Command.STOP path in processPacketIn method by injecting a broadcast packet.
     */
    @Test
    public void testProcessPacketInStop() {
        Command cmd = hostManager.processPacketIn(sw1, pktIn, (Ethernet) pkt0);
        assertEquals(Command.STOP, cmd);
    }

    /**
     * Test add a host from the information from packet.
     * @throws FloodlightModuleException
     */
    @Test
    public void testAddHost() throws FloodlightModuleException {
        Ethernet eth = (Ethernet) pkt1;
        Long longmac = eth.getSourceMAC().toLong();
        Host srcHost = hostManager.getSourceHostFromPacket(eth, sw1Dpid, sw1DevPort);

        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(HostManager.class));
        EasyMock.expectLastCall();
        floodlightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
        EasyMock.expectLastCall();
        replay(floodlightProvider);

        hostManager.init(modContext);
        hostManager.startUp(modContext);
        hostManager.addHost(longmac, srcHost);

        EasyMock.verify(floodlightProvider);
    }

    /**
     * Test delete a host.
     * @throws FloodlightModuleException
     */
    @Test
    public void testDeleteHost() throws FloodlightModuleException {
        Ethernet eth = (Ethernet) pkt1;
        Host srcHost = hostManager.getSourceHostFromPacket(eth, sw1Dpid, sw1DevPort);

        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(HostManager.class));
        EasyMock.expectLastCall();
        floodlightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
        EasyMock.expectLastCall();
        replay(floodlightProvider);

        hostManager.init(modContext);
        hostManager.startUp(modContext);
        hostManager.deleteHost(srcHost);

        EasyMock.verify(floodlightProvider);
    }

    /**
     * Test delete a host by using its source mac address.
     * @throws FloodlightModuleException
     */
    @Test
    public void testDeleteHostByMac() throws FloodlightModuleException {
        Ethernet eth = (Ethernet) pkt1;
        MACAddress mac = eth.getSourceMAC();

        floodlightProvider.addOFMessageListener(EasyMock.eq(OFType.PACKET_IN), EasyMock.isA(HostManager.class));
        EasyMock.expectLastCall();
        floodlightProvider.publishUpdate(EasyMock.isA(IUpdate.class));
        EasyMock.expectLastCall();
        replay(floodlightProvider);

        hostManager.init(modContext);
        hostManager.startUp(modContext);
        hostManager.deleteHostByMac(mac);

        EasyMock.verify(floodlightProvider);
    }
}
