/*
 * Copyright 2014-2015 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.ipv6;

import org.junit.BeforeClass;
import org.junit.Test;
import org.onlab.packet.Data;
import org.onlab.packet.UDP;

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

/**
 * Tests for class {@link Routing}.
 */
public class RoutingTest {
    private static Data data;
    private static UDP udp;
    private static byte[] routingData = {
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
            (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 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) 0x11, (byte) 0x02, (byte) 0x00, (byte) 0x03,
                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                (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
        };
        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() {
        Routing routing = new Routing();
        routing.setNextHeader((byte) 0x11);
        routing.setHeaderExtLength((byte) 0x02);
        routing.setRoutingType((byte) 0x00);
        routing.setSegmntsLeft((byte) 0x03);
        routing.setRoutingData(routingData);
        routing.setPayload(udp);

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

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

        assertThat(routing.getNextHeader(), is((byte) 0x11));
        assertThat(routing.getHeaderExtLength(), is((byte) 0x02));
        assertThat(routing.getRoutingType(), is((byte) 0x00));
        assertThat(routing.getSegmentsLeft(), is((byte) 0x03));
        assertArrayEquals(routing.getRoutingData(), routingData);
    }

    /**
     * Tests comparator.
     */
    @Test
    public void testEqual() {
        Routing routing1 = new Routing();
        routing1.setNextHeader((byte) 0x11);
        routing1.setHeaderExtLength((byte) 0x02);
        routing1.setRoutingType((byte) 0x00);
        routing1.setSegmntsLeft((byte) 0x03);
        routing1.setRoutingData(routingData);

        Routing routing2 = new Routing();
        routing2.setNextHeader((byte) 0x11);
        routing2.setHeaderExtLength((byte) 0x02);
        routing2.setRoutingType((byte) 0x00);
        routing2.setSegmntsLeft((byte) 0x02);
        routing2.setRoutingData(routingData);

        assertTrue(routing1.equals(routing1));
        assertFalse(routing1.equals(routing2));
    }
}
