/*
 * 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.lisp.msg.types;

import io.netty.buffer.ByteBuf;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import org.onosproject.lisp.msg.exceptions.LispWriterException;

import java.util.Objects;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * AS Numbers type LCAF address class.
 * <p>
 * AS Number type is defined in draft-ietf-lisp-lcaf-22
 * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-22#page-9
 *
 * <pre>
 * {@literal
 *  0                   1                   2                   3
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |           AFI = 16387         |     Rsvd1     |     Flags     |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |   Type = 3    |     Rsvd2     |             Length            |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                           AS Number                           |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |              AFI = x          |         Address  ...          |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * }</pre>
 */
public final class LispAsLcafAddress extends LispLcafAddress {

    private final LispAfiAddress address;
    private final int asNumber;

    /**
     * Initializes AS numbers type LCAF address.
     *
     * @param asNumber AS number
     * @param address  AFI address
     */
    private LispAsLcafAddress(int asNumber, LispAfiAddress address) {
        super(LispCanonicalAddressFormatEnum.AS);
        this.asNumber = asNumber;
        this.address = address;
    }

    /**
     * Obtains address.
     *
     * @return address
     */
    public LispAfiAddress getAddress() {
        return address;
    }

    /**
     * Obtains AS number.
     *
     * @return AS number
     */
    public int getAsNumber() {
        return asNumber;
    }

    @Override
    public int hashCode() {
        return Objects.hash(asNumber, address);
    }

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

        if (obj instanceof LispAsLcafAddress) {
            final LispAsLcafAddress other = (LispAsLcafAddress) obj;
            return Objects.equals(this.asNumber, other.asNumber) &&
                    Objects.equals(this.address, other.address);
        }
        return false;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("asNumber", asNumber)
                .add("address", address)
                .toString();
    }

    public static final class AsAddressBuilder
                                extends LcafAddressBuilder<AsAddressBuilder> {
        private int asNumber;
        private LispAfiAddress address;

        /**
         * Sets AS number.
         *
         * @param asNumber AS number
         * @return AsAddressBuilder object
         */
        public AsAddressBuilder withAsNumber(int asNumber) {
            this.asNumber = asNumber;
            return this;
        }

        /**
         * Sets AFI address.
         *
         * @param address AFI address
         * @return AsAddressBuilder object
         */
        public AsAddressBuilder withAddress(LispAfiAddress address) {
            this.address = address;
            return this;
        }

        /**
         * Builds LispAsLcafAddress instance.
         *
         * @return LispAsLcafAddress instance
         */
        public LispAsLcafAddress build() {

            checkNotNull(address, "Must specify an address");

            return new LispAsLcafAddress(asNumber, address);
        }
    }

    /**
     * AS number LCAF address reader class.
     */
    public static class AsLcafAddressReader
                        implements LispAddressReader<LispAsLcafAddress> {

        @Override
        public LispAsLcafAddress readFrom(ByteBuf byteBuf)
                                    throws LispParseError, LispReaderException {

            LispLcafAddress.deserializeCommon(byteBuf);

            int asNumber = (int) byteBuf.readUnsignedInt();
            LispAfiAddress address = new AfiAddressReader().readFrom(byteBuf);

            return new AsAddressBuilder()
                            .withAsNumber(asNumber)
                            .withAddress(address)
                            .build();
        }
    }

    /**
     * AS number LCAF address writer class.
     */
    public static class AsLcafAddressWriter
                        implements LispAddressWriter<LispAsLcafAddress> {

        @Override
        public void writeTo(ByteBuf byteBuf, LispAsLcafAddress address)
                                                    throws LispWriterException {

            int lcafIndex = byteBuf.writerIndex();
            LispLcafAddress.serializeCommon(byteBuf, address);

            byteBuf.writeInt(address.getAsNumber());

            new AfiAddressWriter().writeTo(byteBuf, address.getAddress());

            LispLcafAddress.updateLength(lcafIndex, byteBuf);
        }
    }
}
