/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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.util;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.primitives.Ints;

/**
 * Provides methods to parse attribute header, validate length and type.
 */
public class Validation {
    private static final Logger log = LoggerFactory.getLogger(Validation.class);
    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 = (byte) 0x10;
    public static final byte IPV4_SIZE = 4;
    private boolean firstBit;
    private boolean secondBit;
    private boolean thirdBit;
    private boolean fourthBit;
    private int len;
    private boolean isShort;

    /**
     * Constructor to initialize parameter.
     *
     * @param firstBit in AttributeFlags
     * @param secondBit in AttributeFlags
     * @param thirdBit in AttributeFlags
     * @param fourthBit in AttributeFlags
     * @param len length
     * @param isShort true if length is read as short otherwise false
     */
    Validation(boolean firstBit, boolean secondBit, boolean thirdBit, boolean fourthBit, int len, boolean isShort) {
        this.firstBit = firstBit;
        this.secondBit = secondBit;
        this.thirdBit = thirdBit;
        this.fourthBit = fourthBit;
        this.len = len;
        this.isShort = isShort;
    }

    /**
     * Parses attribute Header.
     *
     * @param cb ChannelBuffer
     * @return object of Validation
     */
    public static Validation parseAttributeHeader(ChannelBuffer cb) {

        boolean firstBit;
        boolean secondBit;
        boolean thirdBit;
        boolean fourthBit;
        boolean isShort;
        byte flags = cb.readByte();
        byte typeCode = cb.readByte();
        byte temp = flags;
        //first Bit : Optional (1) or well-known (0)
        firstBit = ((temp & FIRST_BIT) == FIRST_BIT);
        //second Bit : Transitive (1) or non-Transitive (0)
        secondBit = ((temp & SECOND_BIT) == SECOND_BIT);
        //third Bit : partial (1) or complete (0)
        thirdBit = ((temp & THIRD_BIT) == THIRD_BIT);
        //forth Bit(Extended Length bit) : Attribute Length is 1 octects (0) or 2 octects (1)
        fourthBit = ((temp & FOURTH_BIT) == FOURTH_BIT);
        int len;
        if (fourthBit) {
            isShort = true;
            short length = cb.readShort();
            len = length;
        } else {
            isShort = false;
            byte length = cb.readByte();
            len = length;
        }
        return new Validation(firstBit, secondBit, thirdBit, fourthBit, len, isShort);
    }

    /**
     * Throws exception if length is not correct.
     *
     * @param errorCode Error code
     * @param subErrCode Sub Error Code
     * @param length erroneous length
     * @throws BgpParseException for erroneous length
     */
    public static void validateLen(byte errorCode, byte subErrCode, int length) throws BgpParseException {
        byte[] errLen = Ints.toByteArray(length);
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(errLen);
        throw new BgpParseException(errorCode, subErrCode, buffer);
    }

    /**
     * Throws exception if type is not correct.
     *
     * @param errorCode Error code
     * @param subErrCode Sub Error Code
     * @param type erroneous type
     * @throws BgpParseException for erroneous type
     */
    public static void validateType(byte errorCode, byte subErrCode, int type) throws BgpParseException {
        byte[] errType = Ints.toByteArray(type);
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(errType);
        throw new BgpParseException(errorCode, subErrCode, buffer);
    }

    /**
     * Convert byte array to InetAddress.
     *
     * @param length of IpAddress
     * @param cb channelBuffer
     * @return InetAddress
     */
    public static InetAddress toInetAddress(int length, ChannelBuffer cb) {
        byte[] address = new byte[length];
        cb.readBytes(address, 0, length);
        InetAddress ipAddress = null;
        try {
            ipAddress = InetAddress.getByAddress(address);
        } catch (UnknownHostException e) {
             log.info("InetAddress convertion failed");
        }
        return ipAddress;
    }
    /**
     * Convert byte array to MacAddress.
     *
     * @param length of MacAddress
     * @param cb channelBuffer
     * @return macAddress
     */
    public static MacAddress toMacAddress(int length, ChannelBuffer cb) {
        byte[] address = new byte[length];
        cb.readBytes(address, 0, length);
        MacAddress macAddress = MacAddress.valueOf(address);
        return macAddress;
    }
    /**
     * Returns first bit in type flags.
     *
     * @return first bit in type flags
     */
    public boolean getFirstBit() {
        return this.firstBit;
    }

    /**
     * Returns second bit in type flags.
     *
     * @return second bit in type flags
     */
    public boolean getSecondBit() {
        return this.secondBit;
    }

    /**
     * Returns third bit in type flags.
     *
     * @return third bit in type flags
     */
    public boolean getThirdBit() {
        return this.thirdBit;
    }

    /**
     * Returns fourth bit in type flags.
     *
     * @return fourth bit in type flags
     */
    public boolean getFourthBit() {
        return this.fourthBit;
    }

    /**
     * Returns attribute length.
     *
     * @return attribute length
     */
    public int getLength() {
        return this.len;
    }

    /**
     * Returns whether attribute length read in short or byte.
     *
     * @return whether attribute length read in short or byte
     */
    public boolean isShort() {
        return this.isShort;
    }

    /**
     * Converts byte array of prefix value to IpPrefix object.
     *
     * @param value byte array of prefix value
     * @param length prefix length in bits
     * @return object of IpPrefix
     */
    public static IpPrefix bytesToPrefix(byte[] value, int length) {
        if (value.length != IPV4_SIZE) {
            value = Arrays.copyOf(value, IPV4_SIZE);
        }
        IpPrefix ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, length);
        return ipPrefix;
    }
}