package net.onrc.onos.core.packet;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;

import org.junit.Before;
import org.junit.Test;

public class PacketTest {
    protected IPacket pkt1, pkt2, pkt3, pkt4;
    protected IPacket dummyPkt;
    protected IPacket[] packets;
    
    @Before
    public void setUp() {
        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}))));
        
        this.pkt2 = new Ethernet()
        .setSourceMACAddress("00:44:33:22:11:01")
        .setDestinationMACAddress("00:11:22:33:44:55")
        .setEtherType(Ethernet.TYPE_ARP)
        .setVlanID((short)5)
        .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.pkt3 = 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.pkt4 = new Ethernet()
        .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
        .setSourceMACAddress("00:11:33:55:77:01")
        .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}))));
        
        this.dummyPkt =  new IPv4()
        .setTtl((byte) 32)
        .setSourceAddress("1.2.3.4")
        .setDestinationAddress("5.6.7.8");
        
        this.packets = new IPacket[] { pkt1, pkt2, pkt3, pkt4 };
    }
    
    protected void doTestClone(IPacket pkt) {
        if (pkt.getPayload() != null)
            doTestClone(pkt.getPayload());
        IPacket newPkt = (IPacket)pkt.clone();
        assertSame(pkt.getClass(), newPkt.getClass());
        assertNotSame(pkt, newPkt);
        assertSame(pkt.getParent(), newPkt.getParent());
        assertEquals(pkt, newPkt);
        assertEquals(pkt.getPayload(), newPkt.getPayload());
        if (pkt.getPayload() != null)
            assertNotSame(pkt.getPayload(), newPkt.getPayload());
        
        if (pkt instanceof Ethernet) {
            Ethernet eth = (Ethernet)pkt;
            Ethernet newEth = (Ethernet)newPkt;
            newEth.setDestinationMACAddress(new byte[] { 1,2,3,4,5,6});
            assertEquals(false, newEth.getDestinationMAC()
                                .equals(eth.getDestinationMAC()));
            assertEquals(false, newPkt.equals(pkt));
        }
        if (pkt instanceof ARP) {
            ARP arp = (ARP)pkt;
            ARP newArp = (ARP)newPkt;
            newArp.setSenderProtocolAddress(new byte[] {1,2,3,4});
            assertEquals(false, newArp.getSenderProtocolAddress()
                                .equals(arp.getSenderProtocolAddress()));
            assertEquals(false, newPkt.equals(pkt));
        }
        
        byte[] dummyData = dummyPkt.serialize().clone();
        newPkt = (IPacket)pkt.clone();
        newPkt.deserialize(dummyData, 0, dummyData.length);
        assertEquals(false, newPkt.equals(pkt));
    }
    
    @Test
    public void testClone() {
        for (IPacket pkt: packets) {
            doTestClone(pkt);
        }
    }
    
}
