/*
 * 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));
    }
}
