/*
 * 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.bgpio.types.attr;

import java.util.Objects;

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.types.BgpErrorType;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.util.Validation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Implements BGP link IGP metric attribute.
 */
public class BgpLinkAttrIgpMetric implements BgpValueType {

    protected static final Logger log = LoggerFactory
            .getLogger(BgpLinkAttrIgpMetric.class);

    public static final int ATTRLINK_IGPMETRIC = 1095;
    public static final int ATTRLINK_MAX_LEN = 3;

    /* Variable metric length based on protocol */
    public static final int ISIS_SMALL_METRIC = 1;
    public static final int OSPF_LINK_METRIC = 2;
    public static final int ISIS_WIDE_METRIC = 3;

    /* IGP Metric */
    private final int igpMetric;
    private final int igpMetricLen;

    /**
     * Constructor to initialize the value.
     *
     * @param igpMetric 3 byte IGP metric data.
     * @param igpMetricLen length of IGP metric data.
     */
    public BgpLinkAttrIgpMetric(final int igpMetric, final int igpMetricLen) {
        this.igpMetric = igpMetric;
        this.igpMetricLen = igpMetricLen;
    }

    /**
     * Returns object of this class with specified values.
     *
     * @param igpMetric 3 byte IGP metric data.
     * @param igpMetricLen length of IGP metric data.
     * @return object of BgpLinkAttrIgpMetric
     */
    public static BgpLinkAttrIgpMetric of(final int igpMetric,
                                          final int igpMetricLen) {
        return new BgpLinkAttrIgpMetric(igpMetric, igpMetricLen);
    }

    /**
     * Reads the BGP link attributes IGP Metric.
     *
     * @param cb Channel buffer
     * @return object of type BgpLinkAttrIgpMetric
     * @throws BgpParseException while parsing BgpLinkAttrIgpMetric
     */
    public static BgpLinkAttrIgpMetric read(ChannelBuffer cb)
            throws BgpParseException {

        short linkigp;
        int igpMetric = 0;
        int igpMetricLen = 0;

        short lsAttrLength = cb.readShort();

        if (cb.readableBytes() < lsAttrLength
                || lsAttrLength > ATTRLINK_MAX_LEN) {
            Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR,
                                   BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
                                   lsAttrLength);
        }

        switch (lsAttrLength) {
        case ISIS_SMALL_METRIC:
            igpMetric = cb.readByte();
            igpMetricLen = ISIS_SMALL_METRIC;
            break;
        case OSPF_LINK_METRIC:
            igpMetric = cb.readShort();
            igpMetricLen = OSPF_LINK_METRIC;
            break;
        case ISIS_WIDE_METRIC:
            linkigp = cb.readShort();
            igpMetric = cb.readByte();
            igpMetric = (igpMetric << 16) | linkigp;
            igpMetricLen = ISIS_WIDE_METRIC;
            break;
        default: // validation is already in place
            break;
        }

        return BgpLinkAttrIgpMetric.of(igpMetric, igpMetricLen);
    }

    /**
     * Returns the variable length IGP metric data.
     *
     * @return IGP metric data
     */
    public int attrLinkIgpMetric() {
        return igpMetric;
    }

    /**
     * Returns IGP metric data length.
     *
     * @return IGP metric length
     */
    public int attrLinkIgpMetricLength() {
        return igpMetricLen;
    }

    @Override
    public short getType() {
        return ATTRLINK_IGPMETRIC;
    }

    @Override
    public int hashCode() {
        return Objects.hash(igpMetric, igpMetricLen);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj instanceof BgpLinkAttrIgpMetric) {
            BgpLinkAttrIgpMetric other = (BgpLinkAttrIgpMetric) obj;
            return Objects.equals(igpMetric, other.igpMetric)
                    && Objects.equals(igpMetricLen, other.igpMetricLen);
        }
        return false;
    }

    @Override
    public int write(ChannelBuffer cb) {
        // TODO This will be implemented in the next version
        return 0;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("igpMetric", igpMetric).add("igpMetricLen", igpMetricLen)
                .toString();
    }

    @Override
    public int compareTo(Object o) {
        // TODO Auto-generated method stub
        return 0;
    }
}
