/*
 * 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;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;

import static org.slf4j.LoggerFactory.getLogger;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.packet.PacketUtils.checkInput;


/**
 * Implements IGMP control packet format.
 */
public class IGMP extends BasePacket {
    private final Logger log = getLogger(getClass());

    public static final byte TYPE_IGMPV3_MEMBERSHIP_QUERY = 0x11;
    public static final byte TYPE_IGMPV1_MEMBERSHIP_REPORT = 0x12;
    public static final byte TYPE_IGMPV2_MEMBERSHIP_REPORT = 0x16;
    public static final byte TYPE_IGMPV2_LEAVE_GROUP = 0x17;
    public static final byte TYPE_IGMPV3_MEMBERSHIP_REPORT = 0x22;
    public static final Map<Byte, Deserializer<? extends IPacket>> PROTOCOL_DESERIALIZER_MAP = new HashMap<>();

    public static final int MINIMUM_HEADER_LEN = 12;

    List<IGMPGroup> groups = new ArrayList<>();

    // Fields contained in the IGMP header
    private byte igmpType;
    private byte resField = 0;
    private short checksum = 0;

    private byte[] unsupportTypeData;

    public IGMP() {
    }

    /**
     * Get the IGMP message type.
     *
     * @return the IGMP message type
     */
    public byte getIgmpType() {
        return igmpType;
    }

    /**
     * Set the IGMP message type.
     *
     * @param msgType IGMP message type
     */
    public void setIgmpType(byte msgType) {
        igmpType = msgType;
    }

    /**
     * Get the checksum of this message.
     *
     * @return the checksum
     */
    public short getChecksum() {
        return checksum;
    }

    /**
     * get the Max Resp Code.
     *
     * @return The Maximum Time allowed before before sending a responding report.
     */
    public byte getMaxRespField() {
        return resField;
    }

    /**
     * Set the Max Resp Code.
     *
     * @param respCode the Maximum Response Code.
     */
    public void setMaxRespCode(byte respCode) {
        if (igmpType != IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY) {
            log.debug("Requesting the max response code for an incorrect field: ");
        }
        this.resField = respCode;
    }

    /**
     * Get the list of IGMPGroups.  The group objects will be either IGMPQuery or IGMPMembership
     * depending on the IGMP message type.  For IGMP Query, the groups list should only be
     * one group.
     *
     * @return The list of IGMP groups.
     */
    public List<IGMPGroup> getGroups() {
        return groups;
    }

    /**
     * Add a multicast group to this IGMP message.
     *
     * @param group the IGMPGroup will be IGMPQuery or IGMPMembership depending on the message type.
     * @return true if group was valid and added, false otherwise.
     */
    public boolean addGroup(IGMPGroup group) {
        checkNotNull(group);
        switch (this.igmpType) {
            case TYPE_IGMPV3_MEMBERSHIP_QUERY:
                if (group instanceof IGMPMembership) {
                    return false;
                }

                if (group.sources.size() > 1) {
                    return false;
                }
                break;

            case TYPE_IGMPV3_MEMBERSHIP_REPORT:
                if (group instanceof IGMPMembership) {
                    return false;
                }
                break;

            default:
                log.debug("Warning no IGMP message type has been set");
        }

        this.groups.add(group);
        return true;
    }

    /**
     * Serialize this IGMP packet.  This will take care
     * of serializing IGMPv3 Queries and IGMPv3 Membership
     * Reports.
     *
     * @return the serialized IGMP message
     */
    @Override
    public byte[] serialize() {
        byte [] data = new byte[8915];

        ByteBuffer bb = ByteBuffer.wrap(data);
        bb.put(this.getIgmpType());

        // reserved or max resp code depending on type.
        bb.put(this.resField);

        // Must calculate checksum
        bb.putShort((short) 0);

        switch (this.igmpType) {

            case IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT:
                // reserved
                bb.putShort((short) 0);
                // Number of groups
                bb.putShort((short) groups.size());
                // Fall through

            case IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY:

                for (IGMPGroup grp : groups) {
                    grp.serialize(bb);
                }
                break;

            default:
                bb.put(this.unsupportTypeData);
                break;
        }

        int size = bb.position();
        bb.position(0);
        byte [] rdata = new byte[size];
        bb.get(rdata, 0, size);
        return rdata;
    }

    /**
     * Deserialize an IGMP message.
     *
     * @param data bytes to deserialize
     * @param offset offset to start deserializing from
     * @param length length of the data to deserialize
     * @return populated IGMP object
     */
    @Override
    public IPacket deserialize(final byte[] data, final int offset,
                               final int length) {

        IGMP igmp = new IGMP();
        try {
            igmp = IGMP.deserializer().deserialize(data, offset, length);
        } catch (DeserializationException e) {
            log.error(e.getStackTrace().toString());
            return this;
        }
        this.igmpType = igmp.igmpType;
        this.resField = igmp.resField;
        this.checksum = igmp.checksum;
        this.groups = igmp.groups;
        return this;
    }

    /**
     * Deserializer function for IPv4 packets.
     *
     * @return deserializer function
     */
    public static Deserializer<IGMP> deserializer() {
        return (data, offset, length) -> {
            checkInput(data, offset, length, MINIMUM_HEADER_LEN);

            IGMP igmp = new IGMP();

            ByteBuffer bb = ByteBuffer.wrap(data);
            igmp.igmpType = bb.get();
            igmp.resField = bb.get();
            igmp.checksum = bb.getShort();
            int len = MINIMUM_HEADER_LEN;
            String msg;

            switch (igmp.igmpType) {

                case TYPE_IGMPV3_MEMBERSHIP_QUERY:
                    IGMPQuery qgroup = new IGMPQuery();
                    qgroup.deserialize(bb);
                    igmp.groups.add(qgroup);
                    break;

                case TYPE_IGMPV3_MEMBERSHIP_REPORT:
                    bb.getShort();  // Ignore resvd
                    int ngrps = bb.getShort();

                    for (; ngrps > 0; ngrps--) {
                        IGMPMembership mgroup = new IGMPMembership();
                        mgroup.deserialize(bb);
                        igmp.groups.add(mgroup);
                    }
                    break;

                /*
                 * NOTE: according to the IGMPv3 spec. These previous IGMP type fields
                 * must be supported.  At this time we are going to <b>assume</b> we run
                 * in a modern network where all devices are IGMPv3 capable.
                 */
                case TYPE_IGMPV1_MEMBERSHIP_REPORT:
                case TYPE_IGMPV2_MEMBERSHIP_REPORT:
                case TYPE_IGMPV2_LEAVE_GROUP:
                    igmp.unsupportTypeData = bb.array();  // Is this the entire array?
                    msg = "IGMP message type: " + igmp.igmpType + " is not supported";
                    igmp.log.debug(msg);
                    break;

                default:
                    msg = "IGMP message type: " + igmp.igmpType + " is not recognized";
                    igmp.unsupportTypeData = bb.array();
                    igmp.log.debug(msg);
                    break;
            }
            return igmp;
        };
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (!super.equals(obj)) {
            return false;
        }
        if (!(obj instanceof IGMP)) {
            return false;
        }
        final IGMP other = (IGMP) obj;
        if (this.igmpType != other.igmpType) {
            return false;
        }
        if (this.resField != other.resField) {
            return false;
        }
        if (this.checksum != other.checksum) {
            return false;
        }
        if (this.groups.size() != other.groups.size()) {
            return false;
        }
        // TODO: equals should be true regardless of order.
        if (!groups.equals(other.groups)) {
            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.igmpType;
        result = prime * result + this.groups.size();
        result = prime * result + this.resField;
        result = prime * result + this.checksum;
        result = prime * result + this.groups.hashCode();
        return result;
    }
}
