/*
 * Copyright 2016-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.types;

import com.google.common.base.MoreObjects;

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.util.Validation;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
 * Provides implementation of BGP wide community integer subtlv.
 */
public class WideCommunityInteger implements BgpValueType {
    public static final short TYPE = 4;
    private List<Integer> integer;

    /**
     * Creates an instance of wide community integer subtlv.
     *
     * @param integer integer
     */
    public WideCommunityInteger(List<Integer> integer) {
        this.integer = integer;
    }

    /**
     * Returns object of this class with specified values.
     *
     * @param integer wide community subtlv integer
     * @return object of WideCommunityInteger
     */
    public static WideCommunityInteger of(List<Integer> integer) {
        return new WideCommunityInteger(integer);
    }

    /**
     * Returns wide community subtlv integer.
     *
     * @return wide community subtlv integer
     */
    public List<Integer> integer() {
        return integer;
    }

    /**
     * Sets wide community subtlv integer.
     *
     * @param integer wide community subtlv integer
     */
    public void setInteger(List<Integer> integer) {
        this.integer = integer;
    }

    @Override
    public int hashCode() {
        return Objects.hash(integer);
    }

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

        if (obj == null) {
            return false;
        }

        if (obj instanceof WideCommunityInteger) {
            WideCommunityInteger other = (WideCommunityInteger) obj;
            return Objects.equals(integer, other.integer);
        }
        return false;
    }

    @Override
    public int write(ChannelBuffer c) {
        int iLenStartIndex = c.writerIndex();

        Iterator<Integer> listIterator = integer.iterator();
        c.writeByte(TYPE);

        int iLengthIndex = c.writerIndex();
        c.writeShort(0);

        while (listIterator.hasNext()) {
            Integer integer = listIterator.next();
            c.writeInt(integer);
        }

        int length = c.writerIndex() - iLengthIndex;
        c.setShort(iLengthIndex, (short) (length - 2));

        return c.writerIndex() - iLenStartIndex;
    }

    /**
     * Reads the channel buffer and returns object of WideCommunityInteger.
     *
     * @param c ChannelBuffer
     * @return object of WideCommunityInteger
     * @throws BgpParseException on read error
     */
    public static WideCommunityInteger read(ChannelBuffer c) throws BgpParseException {

        List<Integer> integer = new ArrayList<>();
        short length;

        if (c.readableBytes() < 2) {
            Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
                                   c.readableBytes());
        }

        length = c.readShort();
        if (length == 0) {
            return new WideCommunityInteger(integer);
        }

        if (c.readableBytes() < length) {
            Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
                                   c.readableBytes());
        }

        while (c.readableBytes() > 0) {
            if (c.readableBytes() < 4) {
                Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
                                       c.readableBytes());
            }
            integer.add(c.readInt());
        }

        return new WideCommunityInteger(integer);
    }

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

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

    @Override
    public short getType() {
        // TODO Auto-generated method stub
        return 0;
    }
}
