/*
 * Copyright 2014-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 java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import static com.google.common.base.MoreObjects.toStringHelper;
import static org.onlab.packet.PacketUtils.*;

/**
 * Representation of an LLDP Packet.
 */
public class LLDP extends BasePacket {
    public static final byte CHASSIS_TLV_TYPE = 1;
    public static final short CHASSIS_TLV_SIZE = 7;
    public static final byte CHASSIS_TLV_SUBTYPE = 4;

    public static final byte PORT_TLV_TYPE = 2;
    public static final short PORT_TLV_SIZE = 5;
    public static final byte PORT_TLV_SUBTYPE = 2;

    public static final byte TTL_TLV_TYPE = 3;
    public static final short TTL_TLV_SIZE = 2;

    protected LLDPTLV chassisId;
    protected LLDPTLV portId;
    protected LLDPTLV ttl;
    protected List<LLDPTLV> optionalTLVList;
    protected short ethType;

    public LLDP() {
        this.optionalTLVList = new LinkedList<>();
        this.ethType = Ethernet.TYPE_LLDP;
    }

    /**
     * @return the chassisId
     */
    public LLDPTLV getChassisId() {
        return this.chassisId;
    }

    /**
     * @param chassis the chassisId to set
     * @return this
     */
    public LLDP setChassisId(final LLDPTLV chassis) {
        this.chassisId = chassis;
        return this;
    }

    /**
     * @return the portId
     */
    public LLDPTLV getPortId() {
        return this.portId;
    }

    /**
     * @param portId the portId to set
     * @return this
     */
    public LLDP setPortId(final LLDPTLV portId) {
        this.portId = portId;
        return this;
    }

    /**
     * @return the ttl
     */
    public LLDPTLV getTtl() {
        return this.ttl;
    }

    /**
     * @param ttl the ttl to set
     * @return this
     */
    public LLDP setTtl(final LLDPTLV ttl) {
        this.ttl = ttl;
        return this;
    }

    /**
     * @return the optionalTLVList
     */
    public List<LLDPTLV> getOptionalTLVList() {
        return this.optionalTLVList;
    }

    /**
     * @param optionalTLVList the optionalTLVList to set
     * @return this
     */
    public LLDP setOptionalTLVList(final List<LLDPTLV> optionalTLVList) {
        this.optionalTLVList = optionalTLVList;
        return this;
    }

    @Override
    public byte[] serialize() {
        int length = 2 + this.chassisId.getLength() + 2
                + this.portId.getLength() + 2 + this.ttl.getLength() + 2;
        for (final LLDPTLV tlv : this.optionalTLVList) {
            length += 2 + tlv.getLength();
        }

        final byte[] data = new byte[length];
        final ByteBuffer bb = ByteBuffer.wrap(data);
        bb.put(this.chassisId.serialize());
        bb.put(this.portId.serialize());
        bb.put(this.ttl.serialize());
        for (final LLDPTLV tlv : this.optionalTLVList) {
            bb.put(tlv.serialize());
        }
        bb.putShort((short) 0); // End of LLDPDU

        /*
         * if (this.parent != null && this.parent instanceof Ethernet) {
         * ((Ethernet) this.parent).setEtherType(this.ethType); }
         */

        return data;
    }


    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 883;
        int result = super.hashCode();
        result = prime * result
                + (this.chassisId == null ? 0 : this.chassisId.hashCode());
        result = prime * result + this.optionalTLVList.hashCode();
        result = prime * result
                + (this.portId == null ? 0 : this.portId.hashCode());
        result = prime * result + (this.ttl == null ? 0 : this.ttl.hashCode());
        return result;
    }

    /*
     * (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 LLDP)) {
            return false;
        }
        final LLDP other = (LLDP) obj;
        if (this.chassisId == null) {
            if (other.chassisId != null) {
                return false;
            }
        } else if (!this.chassisId.equals(other.chassisId)) {
            return false;
        }
        if (!this.optionalTLVList.equals(other.optionalTLVList)) {
            return false;
        }
        if (this.portId == null) {
            if (other.portId != null) {
                return false;
            }
        } else if (!this.portId.equals(other.portId)) {
            return false;
        }
        if (this.ttl == null) {
            if (other.ttl != null) {
                return false;
            }
        } else if (!this.ttl.equals(other.ttl)) {
            return false;
        }
        return true;
    }

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

            LLDP lldp = new LLDP();

            int currentIndex = 0;

            ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
            LLDPTLV tlv;
            do {
                // Each new TLV must be a minimum of 2 bytes
                // (containing the type and length fields).
                currentIndex += 2;
                checkHeaderLength(length, currentIndex);

                tlv = new LLDPOrganizationalTLV().deserialize(bb);

                // if there was a failure to deserialize stop processing TLVs
                if (tlv == null) {
                    break;
                }
                switch (tlv.getType()) {
                    case 0x0:
                        // can throw this one away, it's just an end delimiter
                        break;
                    case 0x1:
                        lldp.chassisId = tlv;
                        break;
                    case 0x2:
                        lldp.portId = tlv;
                        break;
                    case 0x3:
                        lldp.ttl = tlv;
                        break;
                    default:
                        lldp.optionalTLVList.add(tlv);
                        break;
                }

                currentIndex += tlv.getLength();
            } while (tlv.getType() != 0);

            return lldp;
        };
    }

    @Override
    public String toString() {
        return toStringHelper(getClass())
                .add("chassisId", Arrays.toString(chassisId.getValue()))
                .add("portId", Arrays.toString(portId.getValue()))
                .add("ttl", Arrays.toString(ttl.getValue()))
                .add("ethType", Short.toString(ethType))
                .toString();

        // TODO: need to handle optionalTLVList
    }
}
