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

import static org.onlab.packet.PacketUtils.*;

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

    @Override
    public IPacket deserialize(final byte[] data, final int offset,
                               final int length) {
        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
        LLDPTLV tlv;
        do {
            try {
                tlv = new LLDPOrganizationalTLV().deserialize(bb);
            } catch (DeserializationException e) {
                break;
            }

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

            default:
                this.optionalTLVList.add(tlv);
                break;
            }
        } while (tlv.getType() != 0 && bb.hasRemaining());
        return this;
    }

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

}
