/*
 * Copyright 2015-present 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 com.google.common.collect.ImmutableList;
import org.slf4j.Logger;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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

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

    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;

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

    // Fields contained in the IGMP header
    protected byte igmpType;
    protected byte resField = 0;
    protected 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 abstract void setMaxRespCode(byte 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 ImmutableList.copyOf(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 abstract boolean addGroup(IGMPGroup group);

    /**
     * Serialize this IGMP packet.  This will take care
     * of serializing IGMPv3 Queries and IGMPv3 Membership
     * Reports.
     *
     * @return the serialized IGMP message
     */
    @java.lang.SuppressWarnings("squid:S128") // suppress switch fall through warning
    @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);

        if (this instanceof IGMPv3) {
            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;
            }
        } else if (this instanceof IGMPv2) {
            if (this.groups.isEmpty()) {
                bb.putInt(0);
            } else {
                bb.putInt(groups.get(0).getGaddr().getIp4Address().toInt());
            }
        } else {
            throw new UnsupportedOperationException();
        }

        int size = bb.position();

        // compute checksum if needed
        if (this.checksum == 0) {
            bb.rewind();
            int accumulation = 0;
            for (int i = 0; i < size * 2; ++i) {
                accumulation += 0xffff & bb.getShort();
            }
            accumulation = (accumulation >> 16 & 0xffff)
                    + (accumulation & 0xffff);
            this.checksum = (short) (~accumulation & 0xffff);
            bb.putShort(2, this.checksum);
        }


        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) {

        final IGMP igmp;
        try {
            igmp = IGMP.deserializer().deserialize(data, offset, length);
        } catch (DeserializationException e) {
            log.error("Deserialization exception", e);
            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, IGMPv2.HEADER_LENGTH);

            // we will assume that this is IGMPv2 if the length is 8
            boolean isV2 = length == IGMPv2.HEADER_LENGTH;

            IGMP igmp = isV2 ? new IGMPv2() : new IGMPv3();

            final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
            igmp.igmpType = bb.get();
            igmp.resField = bb.get();
            igmp.checksum = bb.getShort();

            if (isV2) {
                igmp.addGroup(new IGMPQuery(IpAddress.valueOf(bb.getInt()), 0));
                if (igmp.validChecksum()) {
                    return igmp;
                }
                throw new DeserializationException("invalid checksum");
            }

            // second check for IGMPv3
            checkInput(data, offset, length, IGMPv3.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;
        };
    }

    /**
     * Validates the message's checksum.
     *
     * @return true if valid, false if not
     */
    protected abstract boolean validChecksum();

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

    @Override
    public String toString() {
        return toStringHelper(getClass())
                .add("igmpType", Byte.toString(igmpType))
                .add("resField", Byte.toString(resField))
                .add("checksum", Short.toString(checksum))
                .add("unsupportTypeData", Arrays.toString(unsupportTypeData))
                .toString();
        // TODO: need to handle groups
    }

    public static class IGMPv3 extends IGMP {
        public static final int MINIMUM_HEADER_LEN = 12;

        @Override
        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;
        }

        @Override
        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 IGMPQuery) {
                        return false;
                    }
                    break;

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

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

        @Override
        protected boolean validChecksum() {
            return true; //FIXME
        }
    }

    public static class IGMPv2 extends IGMP {
        public static final int HEADER_LENGTH = 8;

        @Override
        public void setMaxRespCode(byte respCode) {
            this.resField = respCode;
        }

        @Override
        public boolean addGroup(IGMPGroup group) {
            if (groups.isEmpty()) {
                groups = ImmutableList.of(group);
                return true;
            }
            return false;
        }

        @Override
        protected boolean validChecksum() {
            int accumulation = (((int) this.igmpType) & 0xff) << 8;
            accumulation += ((int) this.resField) & 0xff;
            if (!groups.isEmpty()) {
                int ipaddr = groups.get(0).getGaddr().getIp4Address().toInt();
                accumulation += (ipaddr >> 16) & 0xffff;
                accumulation += ipaddr & 0xffff;
            }
            accumulation = (accumulation >> 16 & 0xffff)
                    + (accumulation & 0xffff);
            short checksum = (short) (~accumulation & 0xffff);
            return checksum == this.checksum;
        }
    }
}
