/*
 * Copyright 2015 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.onosproject.pcepio.types;

import java.util.Objects;

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.protocol.PcepVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provides SymbolicPathNameTlv.
 */
public class SymbolicPathNameTlv implements PcepValueType {

    /*
     *    SYMBOLIC-PATH-NAME TLV format
     *    Reference :PCEP Extensions for Stateful PCE draft-ietf-pce-stateful-pce-10
     *
         0                   1                   2                   3
         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |           Type=17             |       Length (variable)       |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |                                                               |
         //                      Symbolic Path Name                     //
         |                                                               |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     */
    protected static final Logger log = LoggerFactory.getLogger(SymbolicPathNameTlv.class);

    public static final short TYPE = 17;
    private short hLength;

    private final byte[] rawValue;

    /**
     * Constructor to initialize raw Value.
     *
     * @param rawValue Symbolic path name
     */
    public SymbolicPathNameTlv(byte[] rawValue) {
        this.rawValue = rawValue;
        this.hLength = (short) rawValue.length;
    }

    /**
     * Constructor to initialize raw Value.
     *
     * @param rawValue Symbolic path name
     * @param hLength length of Symbolic path name
     */
    public SymbolicPathNameTlv(byte[] rawValue, short hLength) {
        this.rawValue = rawValue;
        if (0 == hLength) {
            this.hLength = (short) rawValue.length;
        } else {
            this.hLength = hLength;
        }
    }

    /**
     * Creates an object of SymbolicPathNameTlv.
     *
     * @param raw Symbolic path name
     * @param hLength length of Symbolic path name
     * @return object of SymbolicPathNameTlv
     */
    public static SymbolicPathNameTlv of(final byte[] raw, short hLength) {
        return new SymbolicPathNameTlv(raw, hLength);
    }

    /**
     * Returns Symbolic path name.
     *
     * @return Symbolic path name byte array
     */
    public byte[] getValue() {
        return rawValue;
    }

    @Override
    public PcepVersion getVersion() {
        return PcepVersion.PCEP_1;
    }

    @Override
    public short getType() {
        return TYPE;
    }

    @Override
    public short getLength() {
        return hLength;
    }

    @Override
    public int hashCode() {
        return Objects.hash(rawValue);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof SymbolicPathNameTlv) {
            SymbolicPathNameTlv other = (SymbolicPathNameTlv) obj;
            return Objects.equals(this.rawValue, other.rawValue);
        }
        return false;
    }

    @Override
    public int write(ChannelBuffer c) {
        int iLenStartIndex = c.writerIndex();
        c.writeShort(TYPE);
        c.writeShort(hLength);
        c.writeBytes(rawValue);
        return c.writerIndex() - iLenStartIndex;
    }

    /**
     * Reads channel buffer and returns object of SymbolicPathNameTlv.
     *
     * @param c of type channel buffer
     * @param hLength length of bytes to read
     * @return object of SymbolicPathNameTlv
     */
    public static SymbolicPathNameTlv read(ChannelBuffer c, short hLength) {
        byte[] symbolicPathName = new byte[hLength];
        c.readBytes(symbolicPathName, 0, hLength);
        return new SymbolicPathNameTlv(symbolicPathName, hLength);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass()).add("SymbolicPathName ", rawValue).toString();
    }
}
