/*
 * 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 attribute node flag.
 */
public final class BgpAttrNodeFlagBitTlv implements BgpValueType {

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

    public static final int ATTRNODE_FLAGBIT = 1024;

    /* Node flag bit TLV */
    private final boolean bOverloadBit;
    private final boolean bAttachedBit;
    private final boolean bExternalBit;
    private final boolean bAbrBit;

    public static final byte FIRST_BIT = (byte) 0x80;
    public static final byte SECOND_BIT = 0x40;
    public static final byte THIRD_BIT = 0x20;
    public static final byte FOURTH_BIT = 0x01;

    /**
     * Constructor to initialize parameters.
     *
     * @param bOverloadBit Overload bit
     * @param bAttachedBit Attached bit
     * @param bExternalBit External bit
     * @param bAbrBit ABR Bit
     */
    private BgpAttrNodeFlagBitTlv(boolean bOverloadBit, boolean bAttachedBit,
                                  boolean bExternalBit, boolean bAbrBit) {
        this.bOverloadBit = bOverloadBit;
        this.bAttachedBit = bAttachedBit;
        this.bExternalBit = bExternalBit;
        this.bAbrBit = bAbrBit;
    }

    /**
     * Returns object of this class with specified values.
     *
     * @param bOverloadBit Overload bit
     * @param bAttachedBit Attached bit
     * @param bExternalBit External bit
     * @param bAbrBit ABR Bit
     * @return object of BgpAttrNodeFlagBitTlv
     */
    public static BgpAttrNodeFlagBitTlv of(final boolean bOverloadBit,
                                           final boolean bAttachedBit,
                                           final boolean bExternalBit,
                                           final boolean bAbrBit) {
        return new BgpAttrNodeFlagBitTlv(bOverloadBit, bAttachedBit,
                                         bExternalBit, bAbrBit);
    }

    /**
     * Reads the Node Flag Bits.
     *
     * @param cb ChannelBuffer
     * @return attribute node flag bit tlv
     * @throws BgpParseException while parsing BgpAttrNodeFlagBitTlv
     */
    public static BgpAttrNodeFlagBitTlv read(ChannelBuffer cb)
            throws BgpParseException {
        boolean bOverloadBit = false;
        boolean bAttachedBit = false;
        boolean bExternalBit = false;
        boolean bAbrBit = false;

        short lsAttrLength = cb.readShort();

        if ((lsAttrLength != 1) || (cb.readableBytes() < lsAttrLength)) {
            Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR,
                                   BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
                                   lsAttrLength);
        }

        byte nodeFlagBits = cb.readByte();

        bOverloadBit = ((nodeFlagBits & FIRST_BIT) == FIRST_BIT);
        bAttachedBit = ((nodeFlagBits & SECOND_BIT) == SECOND_BIT);
        bExternalBit = ((nodeFlagBits & THIRD_BIT) == THIRD_BIT);
        bAbrBit = ((nodeFlagBits & FOURTH_BIT) == FOURTH_BIT);

        return BgpAttrNodeFlagBitTlv.of(bOverloadBit, bAttachedBit,
                                        bExternalBit, bAbrBit);
    }

    /**
     * Returns Overload Bit.
     *
     * @return Overload Bit
     */
    public boolean overLoadBit() {
        return bOverloadBit;
    }

    /**
     * Returns Attached Bit.
     *
     * @return Attached Bit
     */
    public boolean attachedBit() {
        return bAttachedBit;
    }

    /**
     * Returns External Bit.
     *
     * @return External Bit
     */
    public boolean externalBit() {
        return bExternalBit;
    }

    /**
     * Returns ABR Bit.
     *
     * @return ABR Bit
     */
    public boolean abrBit() {
        return bAbrBit;
    }

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

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

    @Override
    public int hashCode() {
        return Objects.hash(bOverloadBit, bAttachedBit, bExternalBit, bAbrBit);
    }

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

        if (obj instanceof BgpAttrNodeFlagBitTlv) {
            BgpAttrNodeFlagBitTlv other = (BgpAttrNodeFlagBitTlv) obj;
            return Objects.equals(bOverloadBit, other.bOverloadBit)
                    && Objects.equals(bAttachedBit, other.bAttachedBit)
                    && Objects.equals(bExternalBit, other.bExternalBit)
                    && Objects.equals(bAbrBit, other.bAbrBit);
        }
        return false;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("bOverloadBit", bOverloadBit)
                .add("bAttachedBit", bAttachedBit)
                .add("bExternalBit", bExternalBit).add("bAbrBit", bAbrBit)
                .toString();
    }
}
