/*
 * 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 static junit.framework.Assert.assertTrue;

/**
 * Unit tests for IGMP class.
 */
public class IGMPTest {
    private Deserializer<IGMP> deserializer;

    private IGMP igmpQuery;
    private IGMP igmpMembership;

    private Ip4Address gaddr1;
    private Ip4Address gaddr2;
    private Ip4Address saddr1;
    private Ip4Address saddr2;

    @Before
    public void setUp() throws Exception {
        gaddr1 = Ip4Address.valueOf(0xe1010101);
        gaddr2 = Ip4Address.valueOf(0xe2020202);
        saddr1 = Ip4Address.valueOf(0x0a010101);
        saddr2 = Ip4Address.valueOf(0x0b020202);

        deserializer = IGMP.deserializer();

        // Create an IGMP Query object
        igmpQuery = new IGMP();
        igmpQuery.setIgmpType(IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY);
        igmpQuery.setMaxRespCode((byte) 0x7f);
        IGMPQuery q = new IGMPQuery(gaddr1, (byte) 0x7f);
        q.addSource(saddr1);
        q.addSource(saddr2);
        q.setSbit(false);
        igmpQuery.groups.add(q);

        // Create an IGMP Membership Object
        igmpMembership = new IGMP();
        igmpMembership.setIgmpType(IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT);
        IGMPMembership g1 = new IGMPMembership(gaddr1);
        g1.addSource(saddr1);
        g1.addSource(saddr2);
        igmpMembership.groups.add(g1);
        IGMPMembership g2 = new IGMPMembership(gaddr2);
        g2.addSource(saddr1);
        g2.addSource(saddr2);
        igmpMembership.groups.add(g2);
    }

    @Test
    public void testDeserializeBadInput() throws Exception {
        PacketTestUtils.testDeserializeBadInput(deserializer);
    }

    @Test
    public void testDeserializeTruncated() throws Exception {
        byte[] bits = igmpQuery.serialize();
        PacketTestUtils.testDeserializeTruncated(deserializer, bits);

        bits = igmpMembership.serialize();
        PacketTestUtils.testDeserializeTruncated(deserializer, bits);
    }

    @Test
    public void testDeserializeQuery() throws Exception {
        byte[] data = igmpQuery.serialize();
        IGMP igmp = deserializer.deserialize(data, 0, data.length);
        assertTrue(igmp.equals(igmpQuery));
    }

    @Test
    public void testDeserializeMembership() throws Exception {
        byte[] data = igmpMembership.serialize();
        IGMP igmp = deserializer.deserialize(data, 0, data.length);
        assertTrue(igmp.equals(igmpMembership));
    }

    /**
     * Tests toString.
     */
    @Test
    public void testToStringIgmp() throws Exception {
        // TODO: add toString unit test
    }
}
