/*
 * Copyright 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;

import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.pim.PIMAddrUnicast;
import org.onlab.packet.pim.PIMHello;
import org.onlab.packet.pim.PIMJoinPrune;

import static junit.framework.Assert.assertTrue;

public final class PIMTest {

    public static final String SADDR = "10.2.1.2";
    public static final String PIMADDR = "224.0.0.13";
    public static final String PIMUADDR = "10.23.3.5";

    public static final String SADDR1 = "10.1.1.1/32";
    public static final String SADDR2 = "10.1.2.1/32";
    public static final String GADDR1 = "232.1.1.1/32";
    public static final String GADDR2 = "232.1.2.1/32";

    public static final String CPSTR1 = "of:deadbeefball/8";
    public static final String CPSTR2 = "of:deadbeefcafe/3";
    public static final String CPSTR3 = "of:2badcafef00d/3";

    private Deserializer<PIM> deserializer;

    private PIM pimHello;
    private PIMHello hello;

    private PIM pimJoinPrune;
    private PIMJoinPrune joinPrune;

    /**
     * Create PIM Hello and Join/Prune packets to be used in testing.
     *
     * @throws Exception if packet creation fails
     */
    @Before
    public void setUp() throws Exception {

        // Create a PIM Hello
        pimHello = new PIM();
        pimHello.setVersion((byte) 2);
        pimHello.setPIMType((byte) PIM.TYPE_HELLO);
        pimHello.setChecksum((short) 0);

        hello = new PIMHello();
        hello.createDefaultOptions();
        pimHello.setPayload(hello);
        hello.setParent(pimHello);

        // Create PIM Join Prune
        pimJoinPrune = new PIM();
        pimJoinPrune.setVersion((byte) 2);
        pimJoinPrune.setPIMType((byte) PIM.TYPE_JOIN_PRUNE_REQUEST);
        pimJoinPrune.setChecksum((short) 0);

        joinPrune = new PIMJoinPrune();
        joinPrune.setUpstreamAddr(new PIMAddrUnicast(SADDR));
        joinPrune.addJoin(GADDR1, SADDR1);
        joinPrune.addJoin(GADDR2, SADDR2);
        joinPrune.addPrune(GADDR1, SADDR2);
        joinPrune.addPrune(GADDR2, SADDR1);

        pimJoinPrune.setPayload(joinPrune);
        joinPrune.setParent(pimJoinPrune);

        deserializer = PIM.deserializer();
    }

    /**
     * Make sure our deserializer throws an exception if we recieve bad input.
     *
     * @throws Exception if we are given bad input.
     */
    @Test
    public void testDeserializeBadInput() throws Exception {
        PacketTestUtils.testDeserializeBadInput(deserializer);
    }

    /**
     * Verify we throw an exception if we receive a truncated Join/Prune message.
     *
     * @throws Exception if we receive a truncated Join/Prune message.
     */
    @Test
    public void testDeserializeTruncated() throws Exception {
        byte[] bits = pimJoinPrune.serialize();
        PacketTestUtils.testDeserializeTruncated(deserializer, bits);
    }

    /**
     * Verify that we correctly deserialize hello messages.
     *
     * @throws Exception if our input is bad or truncated.
     */
    @Test
    public void testDeserializeHello() throws Exception {
        byte[] data = pimHello.serialize();
        PIM pim = deserializer.deserialize(data, 0, data.length);
        assertTrue(pim.equals(pimHello));
    }

    /**
     * Verify that we correctly deserialize Join/Prune messages.
     *
     * @throws Exception if our input is bad or truncated.
     */
    @Test
    public void testDeserializeJoinPrune() throws Exception {
        byte[] data = pimJoinPrune.serialize();
        PIM pim = deserializer.deserialize(data, 0, data.length);
        assertTrue(pim.equals(pimJoinPrune));
    }

}