/*
 * Copyright 2014 Open Networking Laboratory
 *
 * 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 org.onlab.packet;

import org.junit.BeforeClass;
import org.junit.Test;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;

/**
 * Tests for class {@link IPv6}.
 */
public class IPv6Test {
    private static final byte[] SOURCE_ADDRESS = {
            (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
            (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce
    };
    private static final byte[] DESTINATION_ADDRESS = {
            (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
            (byte) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff, (byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8
    };
    private static Data data;
    private static UDP udp;
    private static byte[] bytePacket;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        data = new Data();
        data.setData("testSerialize".getBytes());
        udp = new UDP();
        udp.setPayload(data);

        byte[] bytePayload = udp.serialize();
        byte[] byteHeader = {
                (byte) 0x69, (byte) 0x31, (byte) 0x35, (byte) 0x79,
                (byte) (bytePayload.length >> 8 & 0xff), (byte) (bytePayload.length & 0xff),
                (byte) 0x11, (byte) 0x20,
                (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
                (byte) 0xca, (byte) 0x2a, (byte) 0x14, (byte) 0xff, (byte) 0xfe, (byte) 0x35, (byte) 0x26, (byte) 0xce,
                (byte) 0x20, (byte) 0x01, (byte) 0x0f, (byte) 0x18, (byte) 0x01, (byte) 0x13, (byte) 0x02, (byte) 0x15,
                (byte) 0xe6, (byte) 0xce, (byte) 0x8f, (byte) 0xff, (byte) 0xfe, (byte) 0x54, (byte) 0x37, (byte) 0xc8,
        };
        bytePacket = new byte[byteHeader.length + bytePayload.length];
        System.arraycopy(byteHeader, 0, bytePacket, 0, byteHeader.length);
        System.arraycopy(bytePayload, 0, bytePacket, byteHeader.length, bytePayload.length);
    }

    /**
     * Tests serialize and setters.
     */
    @Test
    public void testSerialize() {
        IPv6 ipv6 = new IPv6();
        ipv6.setPayload(udp);
        ipv6.setVersion((byte) 6);
        ipv6.setTrafficClass((byte) 0x93);
        ipv6.setFlowLabel(0x13579);
        ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
        ipv6.setHopLimit((byte) 32);
        ipv6.setSourceAddress(SOURCE_ADDRESS);
        ipv6.setDestinationAddress(DESTINATION_ADDRESS);

        assertArrayEquals(ipv6.serialize(), bytePacket);
    }

    /**
     * Tests deserialize and getters.
     */
    @Test
    public void testDeserialize() {
        IPv6 ipv6 = new IPv6();
        ipv6.deserialize(bytePacket, 0, bytePacket.length);

        assertThat(ipv6.getVersion(), is((byte) 6));
        assertThat(ipv6.getTrafficClass(), is((byte) 0x93));
        assertThat(ipv6.getFlowLabel(), is(0x13579));
        assertThat(ipv6.getNextHeader(), is(IPv6.PROTOCOL_UDP));
        assertThat(ipv6.getHopLimit(), is((byte) 32));
        assertArrayEquals(ipv6.getSourceAddress(), SOURCE_ADDRESS);
        assertArrayEquals(ipv6.getDestinationAddress(), DESTINATION_ADDRESS);
    }

    /**
     * Tests comparator.
     */
    @Test
    public void testEqual() {
        IPv6 packet1 = new IPv6();
        packet1.setPayload(udp);
        packet1.setVersion((byte) 6);
        packet1.setTrafficClass((byte) 0x93);
        packet1.setFlowLabel(0x13579);
        packet1.setNextHeader(IPv6.PROTOCOL_UDP);
        packet1.setHopLimit((byte) 32);
        packet1.setSourceAddress(SOURCE_ADDRESS);
        packet1.setDestinationAddress(DESTINATION_ADDRESS);

        IPv6 packet2 = new IPv6();
        packet2.setPayload(udp);
        packet2.setVersion((byte) 6);
        packet2.setTrafficClass((byte) 0x93);
        packet2.setFlowLabel(0x13579);
        packet2.setNextHeader(IPv6.PROTOCOL_UDP);
        packet2.setHopLimit((byte) 32);
        packet2.setSourceAddress(DESTINATION_ADDRESS);
        packet2.setDestinationAddress(SOURCE_ADDRESS);

        assertTrue(packet1.equals(packet1));
        assertFalse(packet1.equals(packet2));
    }
}
