/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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;
    }

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

            final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
            byte igmpType = bb.get();
            boolean isV2;
            if (igmpType == TYPE_IGMPV2_MEMBERSHIP_REPORT  || igmpType == TYPE_IGMPV2_LEAVE_GROUP ||
                    length == IGMPv2.HEADER_LENGTH) {
                isV2 = true;
            } else {
                isV2 = false;
            }

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

            igmp.igmpType = igmpType;
            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;
        }
    }
}
