/*
 * 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 java.nio.ByteBuffer;

public class IGMPQuery extends IGMPGroup {

    // Bits and bytes after the group address
    private byte resv = 0;
    private boolean sbit = false;
    private byte qrv = 2;
    private byte qqic = 0x7d;

    /**
     * Create IGMP Query message.
     *
     * @param gaddr initiaze with a group address.
     * @param auxInfo auxillary info.
     */
    public IGMPQuery(IpAddress gaddr, int auxInfo) {
        super(gaddr, auxInfo);
    }

    /**
     * Create IGMP Query message.
     */
    public IGMPQuery() {
        super();
    }

    /**
     * Is the S flag set?  Telling adjacent routers to suppress normal timer updates.
     *
     * @return true if the flag is set, false otherwise
     */
    public boolean isSbit() {
        return sbit;
    }

    /**
     * Set the S flag.  Default is false.
     *
     * @param sbit true or false
     */
    public void setSbit(boolean sbit) {
        this.sbit = sbit;
    }

    /**
     * Get the Querier Robustness Variable.
     *
     * @return querier robustness value
     */
    public byte getQrv() {
        return qrv;
    }

    /**
     * Set the Querier Robustness Variable. Default is 2.
     *
     * @param qrv new querier robustness value
     */
    public void setQrv(byte qrv) {
        this.qrv = qrv;
    }

    /**
     * Get the reserved field.  Should be zero, but ignored regardless of it's value.
     *
     * @return the reserved field.
     */
    public byte getResv() {
        return resv;
    }

    /**
     * Set the reserved field.  Should be 0 and ignored by receivers.
     *
     * @param resv the reserved field.
     */
    public void setResv(byte resv) {
        this.resv = resv;
    }

    /**
     * Serialize this IGMPQuery.
     *
     * @param bb the ByteBuffer to write into, positioned at the next spot to be written to.
     * @return the serialized message
     */
    @Override
    public byte[] serialize(ByteBuffer bb) {

        bb.put(gaddr.toOctets());
        byte fld = (byte) (0x7 & qrv);
        bb.put(fld);
        bb.put(qqic);
        bb.putShort((short) sources.size());
        for (IpAddress ipaddr : sources) {
            bb.put(ipaddr.toOctets());
        }
        return bb.array();
    }

    /**
     * Deserialize the IGMP Query group structure.
     *
     * @param bb ByteBuffer pointing at the IGMP Query group address
     * @return the IGMP Group object
     */
    public IGMPGroup deserialize(ByteBuffer bb) throws DeserializationException {

        gaddr = Ip4Address.valueOf(bb.getInt());
        byte fld = bb.get();

        // Just ignore the reserved bits
        resv = 0;
        this.sbit = ((fld & 0x8) == 0x8);
        qrv = (byte) (fld & 0x7);

        // QQIC field
        qqic = bb.get();

        // Get the number of sources.
        short nsrcs = bb.getShort();

        // Do a sanity check on the amount of space we have in our buffer.
        int lengthNeeded = (Ip4Address.BYTE_LENGTH * nsrcs);
        PacketUtils.checkHeaderLength(bb.remaining(), lengthNeeded);

        for (; nsrcs > 0; nsrcs--) {
            Ip4Address ipaddr = Ip4Address.valueOf(bb.getInt());
            this.sources.add(ipaddr);
        }
        return this;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#equals()
     */
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof IGMPQuery)) {
            return false;
        }
        IGMPQuery other = (IGMPQuery) obj;

        if (this.sbit != other.sbit) {
            return false;
        }
        if (this.qrv != other.qrv) {
            return false;
        }
        if (this.qqic != other.qqic) {
            return false;
        }
        if (this.sources.size() != other.sources.size()) {
            return false;
        }

        // TODO: make these tolerant of order
        if (!this.sources.equals(other.sources)) {
            return false;
        }

        return true;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 2521;
        int result = super.hashCode();
        result = prime * result + this.gaddr.hashCode();
        result = prime * result + this.qqic;
        result = prime * result + this.qrv;
        result = prime * result + this.sources.hashCode();
        return result;
    }
}
