/**
 *    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 net.onrc.onos.core.packet;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Arrays;

/**
 * The class representing LLDP Organizationally Specific TLV.
 *
 * <!-- CHECKSTYLE IGNORE WriteTag FOR NEXT 1 LINES -->
 * @author Sho Shimizu (sho.shimizu@gmail.com)
 */
public class LLDPOrganizationalTLV extends LLDPTLV {
    public static final int OUI_LENGTH = 3;
    public static final int SUBTYPE_LENGTH = 1;
    public static final byte ORGANIZATIONAL_TLV_TYPE = 127;
    public static final int MAX_INFOSTRING_LENGTH = 507;

    protected byte[] oui;
    protected byte subType;
    private byte[] infoString;

    public LLDPOrganizationalTLV() {
        type = ORGANIZATIONAL_TLV_TYPE;
    }

    /**
     * Set the value of OUI.
     *
     * @param oui The value of OUI to be set.
     * @return This LLDP Organizationally Specific TLV.
     */
    public LLDPOrganizationalTLV setOUI(byte[] oui) {
        if (oui.length != OUI_LENGTH) {
            throw new IllegalArgumentException("The length of OUI must be " + OUI_LENGTH +
                    ", but it is " + oui.length);
        }
        this.oui = Arrays.copyOf(oui, oui.length);
        return this;
    }

    /**
     * Returns the value of the OUI.
     *
     * @return The value of the OUI .
     */
    public byte[] getOUI() {
        return Arrays.copyOf(oui, oui.length);
    }

    /**
     * Set the value of sub type.
     *
     * @param subType The value of sub type to be set.
     * @return This LLDP Organizationally Specific TLV.
     */
    public LLDPOrganizationalTLV setSubType(byte subType) {
        this.subType = subType;
        return this;
    }

    /**
     * Returns the value of the sub type.
     *
     * @return The value of the sub type.
     */
    public byte getSubType() {
        return subType;
    }

    /**
     * Set the value of information string.
     *
     * @param infoString the byte array of the value of information string.
     * @return This LLDP Organizationally Specific TLV.
     */
    public LLDPOrganizationalTLV setInfoString(byte[] infoString) {
        if (infoString.length > MAX_INFOSTRING_LENGTH) {
            throw new IllegalArgumentException("The length of infoString cannot exceed " + MAX_INFOSTRING_LENGTH);
        }
        this.infoString = Arrays.copyOf(infoString, infoString.length);
        return this;
    }

    /**
     * Set the value of information string.
     * The String value is automatically converted into byte array with UTF-8 encoding.
     *
     * @param infoString the String value of information string.
     * @return This LLDP Organizationally Specific TLV.
     */
    public LLDPOrganizationalTLV setInfoString(String infoString) {
        byte[] infoStringBytes = infoString.getBytes(Charset.forName("UTF-8"));
        return setInfoString(infoStringBytes);
    }

    /**
     * Returns the value of information string.
     *
     * @return the value of information string.
     */
    public byte[] getInfoString() {
        return Arrays.copyOf(infoString, infoString.length);
    }

    @Override
    public byte[] serialize() {
        int valueLength = OUI_LENGTH + SUBTYPE_LENGTH + infoString.length;
        value = new byte[valueLength];
        ByteBuffer bb = ByteBuffer.wrap(value);
        bb.put(oui);
        bb.put(subType);
        bb.put(infoString);
        return super.serialize();
    }

    @Override
    public LLDPTLV deserialize(ByteBuffer bb) {
        super.deserialize(bb);
        ByteBuffer optionalField = ByteBuffer.wrap(value);

        byte[] oui = new byte[OUI_LENGTH];
        optionalField.get(oui);
        setOUI(oui);

        setSubType(optionalField.get());

        byte[] infoString = new byte[getLength() - OUI_LENGTH - SUBTYPE_LENGTH];
        optionalField.get(infoString);
        setInfoString(infoString);
        return this;
    }

    @Override
    public int hashCode() {
        final int prime = 1423;
        int result = 1;
        result = prime * result + type;
        result = prime * result + length;
        result = prime * result + Arrays.hashCode(oui);
        result = prime * result + subType;
        result = prime * result + Arrays.hashCode(infoString);
        return result;
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }
        if (!super.equals(o)) {
            return false;
        }
        //
        // NOTE: Subclasses are are considered as change of identity, hence
        // equals() will return false if the class type doesn't match.
        //
        if (getClass() != o.getClass()) {
            return false;
        }
        LLDPOrganizationalTLV other = (LLDPOrganizationalTLV) o;
        if (this.type != other.type) {
            return false;
        }
        if (this.length != other.length) {
            return false;
        }
        if (!Arrays.equals(this.oui, other.oui)) {
            return false;
        }
        if (this.subType != other.subType) {
            return false;
        }
        if (!Arrays.equals(this.infoString, other.infoString)) {
            return false;
        }

        return true;
    }
}
