/*
 * Copyright 2016-present 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.isis.io.isispacket.tlv;

import com.google.common.base.MoreObjects;
import com.google.common.primitives.Bytes;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onlab.packet.Ip4Address;
import org.onosproject.isis.io.util.IsisUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * Representation of metric of internal reachability.
 */
public class MetricOfInternalReachability {
    private Ip4Address ipAddress;
    private Ip4Address subnetAddres;
    private byte defaultMetric;
    private byte delayMetric;
    private byte expenseMetric;
    private byte errorMetric;
    private boolean delayMetricSupported;
    private boolean expenseMetricSupported;
    private boolean errorMetricSupported;
    private boolean defaultIsInternal;
    private boolean defaultDistributionDown;
    private boolean delayIsInternal;
    private boolean expenseIsInternal;
    private boolean errorIsInternal;

    /**
     * Returns the IP address of metric of internal reachability.
     *
     * @return ipAddress IP address of metric of internal reachability
     */
    public Ip4Address getIpAddress() {
        return ipAddress;
    }

    /**
     * Sets the IP address for metric of internal reachability.
     *
     * @param ipAddress ip address
     */
    public void setIpAddress(Ip4Address ipAddress) {
        this.ipAddress = ipAddress;
    }

    /**
     * Returns the subnet address of metric of internal reachability.
     *
     * @return subnetAddres subnet address of metric of internal reachability
     */
    public Ip4Address getSubnetAddres() {
        return subnetAddres;
    }

    /**
     * Sets the subnet address for metric of internal reachability.
     *
     * @param subnetAddres subnet address
     */
    public void setSubnetAddres(Ip4Address subnetAddres) {
        this.subnetAddres = subnetAddres;
    }

    /**
     * Returns error metric is internal or not.
     *
     * @return true if internal else false
     */
    public boolean isErrorIsInternal() {
        return errorIsInternal;
    }

    /**
     * Sets error metric is internal or not.
     *
     * @param errorIsInternal true if internal else false
     */
    public void setErrorIsInternal(boolean errorIsInternal) {
        this.errorIsInternal = errorIsInternal;
    }

    /**
     * Returns expense metric is internal or not.
     *
     * @return true if internal else false
     */
    public boolean isExpenseIsInternal() {
        return expenseIsInternal;
    }

    /**
     * Sets expense metric is internal or not.
     *
     * @param expenseIsInternal true if internal else false
     */
    public void setExpenseIsInternal(boolean expenseIsInternal) {
        this.expenseIsInternal = expenseIsInternal;
    }

    /**
     * Returns delays metric is internal or not.
     *
     * @return true if internal else false
     */
    public boolean isDelayIsInternal() {
        return delayIsInternal;
    }

    /**
     * Sets delay metric is internal or not.
     *
     * @param delayIsInternal true if internal else false
     */
    public void setDelayIsInternal(boolean delayIsInternal) {
        this.delayIsInternal = delayIsInternal;
    }

    /**
     * Returns is default distribution is up or down.
     *
     * @return true if down else false
     */
    public boolean isDefaultDistributionDown() {
        return defaultDistributionDown;
    }

    /**
     * Sets default distribution is up or down.
     *
     * @param defaultDistributionDown true if down else false
     */
    public void setDefaultDistributionDown(boolean defaultDistributionDown) {
        this.defaultDistributionDown = defaultDistributionDown;
    }

    /**
     * Returns is default metric is internal or not.
     *
     * @return true if internal else false
     */
    public boolean isDefaultIsInternal() {
        return defaultIsInternal;
    }

    /**
     * Sets default metric is internal or not.
     *
     * @param defaultIsInternal true is internal else false
     */
    public void setDefaultIsInternal(boolean defaultIsInternal) {
        this.defaultIsInternal = defaultIsInternal;
    }

    /**
     * Returns error metric is supported or not.
     *
     * @return true if supported else false
     */
    public boolean isErrorMetricSupported() {
        return errorMetricSupported;
    }

    /**
     * Sets error metric is supported or not.
     *
     * @param errorMetricSupported true if supported else false
     */
    public void setErrorMetricSupported(boolean errorMetricSupported) {
        this.errorMetricSupported = errorMetricSupported;
    }

    /**
     * Returns expense metric is supported or not.
     *
     * @return true if supported else false
     */
    public boolean isExpenseMetricSupported() {
        return expenseMetricSupported;
    }

    /**
     * Sets expense metric is supported or not.
     *
     * @param expenseMetricSupported true if supported else false
     */
    public void setExpenseMetricSupported(boolean expenseMetricSupported) {
        this.expenseMetricSupported = expenseMetricSupported;
    }

    /**
     * Returns delay metric is supported or not.
     *
     * @return true if supported else false
     */
    public boolean isDelayMetricSupported() {
        return delayMetricSupported;
    }

    /**
     * Sets delay metric is supported or not.
     *
     * @param delayMetricSupported true if supported else false
     */
    public void setDelayMetricSupported(boolean delayMetricSupported) {
        this.delayMetricSupported = delayMetricSupported;
    }

    /**
     * Returns error metric of metric of internal reachability.
     *
     * @return errorMetric error metic
     */
    public byte errorMetric() {
        return errorMetric;
    }

    /**
     * Sets error metric for metric of internal reachability.
     *
     * @param errorMetric error metric
     */
    public void setErrorMetric(byte errorMetric) {
        this.errorMetric = errorMetric;
    }

    /**
     * Returns expense metric of metric of internal reachability.
     *
     * @return expense metric
     */
    public byte expenseMetric() {
        return expenseMetric;
    }

    /**
     * Sets expense metric for metric of internal reachability.
     *
     * @param expenseMetric expense metric
     */
    public void setExpenseMetric(byte expenseMetric) {
        this.expenseMetric = expenseMetric;
    }

    /**
     * Returns delay metric of metric of internal reachability.
     *
     * @return delay metric
     */
    public byte delayMetric() {
        return delayMetric;
    }

    /**
     * Sets delay metric for metric of internal reachability.
     *
     * @param delayMetric delay metric
     */
    public void setDelayMetric(byte delayMetric) {
        this.delayMetric = delayMetric;
    }

    /**
     * Returns default metric of metric of internal reachability.
     *
     * @return default metric
     */
    public byte defaultMetric() {
        return defaultMetric;
    }

    /**
     * Sets default metric for metric of internal reachability.
     *
     * @param defaultMetric default metric
     */
    public void setDefaultMetric(byte defaultMetric) {
        this.defaultMetric = defaultMetric;
    }

    /**
     * Sets the metric of internal reachability
     * values for metric of internal reachability from byte buffer.
     *
     * @param channelBuffer channel Buffer instance
     */
    public void readFrom(ChannelBuffer channelBuffer) {
        byte metric = channelBuffer.readByte();
        this.setDefaultMetric(metric);
        String metricInBinary = Integer.toBinaryString(Byte.toUnsignedInt(metric));
        metricInBinary = IsisUtil.toEightBitBinary(metricInBinary);
        if (metricInBinary.charAt(1) == 0) {
            this.setDefaultIsInternal(true);
        } else {
            this.setDefaultIsInternal(false);
        }
        if (metricInBinary.charAt(0) == 0) {
            this.setDefaultDistributionDown(true);
        } else {
            this.setDefaultDistributionDown(false);
        }
        byte delayMetric = channelBuffer.readByte();
        metricInBinary = Integer.toBinaryString(Byte.toUnsignedInt(delayMetric));
        metricInBinary = IsisUtil.toEightBitBinary(metricInBinary);
        this.setDelayMetric(Byte.parseByte(metricInBinary.substring(5, metricInBinary.length()), 2));
        if (metricInBinary.charAt(1) == 0) {
            this.setDelayIsInternal(true);
        } else {
            this.setDelayIsInternal(false);
        }
        if (metricInBinary.charAt(0) == 0) {
            this.setDelayMetricSupported(true);
        } else {
            this.setDelayMetricSupported(false);
        }
        byte expenseMetric = channelBuffer.readByte();
        metricInBinary = Integer.toBinaryString(Byte.toUnsignedInt(expenseMetric));
        metricInBinary = IsisUtil.toEightBitBinary(metricInBinary);
        this.setExpenseMetric(Byte.parseByte(metricInBinary.substring(5, metricInBinary.length()), 2));
        if (metricInBinary.charAt(1) == 0) {
            this.setExpenseIsInternal(true);
        } else {
            this.setExpenseIsInternal(false);
        }
        if (metricInBinary.charAt(0) == 0) {
            this.setExpenseMetricSupported(true);
        } else {
            this.setExpenseMetricSupported(false);
        }
        byte errorMetric = channelBuffer.readByte();
        metricInBinary = Integer.toBinaryString(Byte.toUnsignedInt(errorMetric));
        metricInBinary = IsisUtil.toEightBitBinary(metricInBinary);
        this.setErrorMetric(Byte.parseByte(metricInBinary.substring(5, metricInBinary.length()), 2));
        if (metricInBinary.charAt(1) == 0) {
            this.setErrorIsInternal(true);
        } else {
            this.setErrorIsInternal(false);
        }
        if (metricInBinary.charAt(0) == 0) {
            this.setErrorMetricSupported(true);
        } else {
            this.setErrorMetricSupported(false);
        }
        List<Byte> byteList = new ArrayList<>();
        while (channelBuffer.readableBytes() > 0) {
            byteList.add(channelBuffer.readByte());
        }
        byte[] tempByteArray = new byte[IsisUtil.FOUR_BYTES];
        channelBuffer.readBytes(tempByteArray, 0, IsisUtil.FOUR_BYTES);
        this.setIpAddress(Ip4Address.valueOf(tempByteArray));

        tempByteArray = new byte[IsisUtil.FOUR_BYTES];
        channelBuffer.readBytes(tempByteArray, 0, IsisUtil.FOUR_BYTES);
        this.setSubnetAddres(Ip4Address.valueOf(tempByteArray));
    }

    /**
     * Returns metric of internal reachability values as bytes of metric of internal reachability.
     *
     * @return byteArray metric of internal reachability values as bytes of metric of internal reachability
     */
    public byte[] asBytes() {
        List<Byte> bytes = new ArrayList<>();
        bytes.add(this.defaultMetric());
        int temp = this.delayMetric();
        String hsbBits = "";
        if (this.isDelayMetricSupported()) {
            hsbBits = "0" + hsbBits;
        } else {
            hsbBits = "1" + hsbBits;
        }
        if (this.isDelayIsInternal()) {
            hsbBits = hsbBits + "0";
        } else {
            hsbBits = hsbBits + "1";
        }
        hsbBits = hsbBits + "00";
        String binary = hsbBits + IsisUtil.toFourBitBinary(Integer.toBinaryString(temp));
        bytes.add((byte) Integer.parseInt(binary, 2));

        temp = this.expenseMetric();
        hsbBits = "";
        if (this.isExpenseMetricSupported()) {
            hsbBits = "0" + hsbBits;
        } else {
            hsbBits = "1" + hsbBits;
        }
        if (this.isExpenseIsInternal()) {
            hsbBits = hsbBits + "0";
        } else {
            hsbBits = hsbBits + "1";
        }
        hsbBits = hsbBits + "00";
        binary = hsbBits + IsisUtil.toFourBitBinary(Integer.toBinaryString(temp));
        bytes.add((byte) Integer.parseInt(binary, 2));

        temp = this.errorMetric();
        hsbBits = "";
        if (this.isErrorMetricSupported()) {
            hsbBits = "0" + hsbBits;
        } else {
            hsbBits = "1" + hsbBits;
        }
        if (this.isExpenseIsInternal()) {
            hsbBits = hsbBits + "0";
        } else {
            hsbBits = hsbBits + "1";
        }
        hsbBits = hsbBits + "00";
        binary = hsbBits + IsisUtil.toFourBitBinary(Integer.toBinaryString(temp));
        bytes.add((byte) Integer.parseInt(binary, 2));

        bytes.addAll(Bytes.asList(this.getIpAddress().toOctets()));
        bytes.addAll(Bytes.asList(this.getSubnetAddres().toOctets()));
        return Bytes.toArray(bytes);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .omitNullValues()
                .add("ipAddress", ipAddress)
                .add("subnetAddres", subnetAddres)
                .add("defaultMetric", defaultMetric)
                .add("delayMetric", delayMetric)
                .add("expenseMetric", expenseMetric)
                .add("errorMetric", errorMetric)
                .add("delayMetricSupported", delayMetricSupported)
                .add("expenseMetricSupported", expenseMetricSupported)
                .add("errorMetricSupported", errorMetricSupported)
                .add("defaultIsInternal", defaultIsInternal)
                .add("defaultDistributionDown", defaultDistributionDown)
                .add("delayIsInternal", delayIsInternal)
                .add("expenseIsInternal", expenseIsInternal)
                .add("errorIsInternal", errorIsInternal)
                .toString();
    }
}