/*
 * 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.lcaf;

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 org.onosproject.lisp.msg.types.LispAddressReader;
import org.onosproject.lisp.msg.types.LispAddressWriter;
import org.onosproject.lisp.msg.types.LispAfiAddress;

import java.util.Objects;

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

/**
 * Source/Dest key type LCAF address class.
 * <p>
 * Source destination key type is defined in draft-ietf-lisp-lcaf-22
 * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-22#page-19
 *
 * <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 = 12   |     Rsvd2     |             Length            |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |            Reserved           |   Source-ML   |    Dest-ML    |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |              AFI = x          |         Source-Prefix ...     |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |              AFI = x          |     Destination-Prefix ...    |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * }</pre>
 */
public final class LispSourceDestLcafAddress extends LispLcafAddress {

    private final LispAfiAddress srcPrefix;
    private final LispAfiAddress dstPrefix;
    private final byte srcMaskLength;
    private final byte dstMaskLength;
    private final short reserved;

    /**
     * Initializes source/dest key type LCAF address.
     *
     * @param reserved      reserved
     * @param srcMaskLength source mask length
     * @param dstMaskLength destination mask length
     * @param srcPrefix     source address prefix
     * @param dstPrefix     destination address prefix
     */
    private LispSourceDestLcafAddress(short reserved, byte srcMaskLength,
                                      byte dstMaskLength,
                                      LispAfiAddress srcPrefix,
                                      LispAfiAddress dstPrefix) {
        super(LispCanonicalAddressFormatEnum.SOURCE_DEST);
        this.reserved = reserved;
        this.srcMaskLength = srcMaskLength;
        this.dstMaskLength = dstMaskLength;
        this.srcPrefix = srcPrefix;
        this.dstPrefix = dstPrefix;
    }

    /**
     * Initializes source/destination key type LCAF address.
     *
     * @param reserved1     reserved1
     * @param reserved2     reserved2
     * @param flag          flag
     * @param length        length
     * @param reserved      reserved
     * @param srcMaskLength source mask length
     * @param dstMaskLength destination mask length
     * @param srcPrefix     source address prefix
     * @param dstPrefix     destination address prefix
     */
    private LispSourceDestLcafAddress(byte reserved1, byte reserved2, byte flag,
                                      short length, short reserved,
                                      byte srcMaskLength, byte dstMaskLength,
                                      LispAfiAddress srcPrefix,
                                      LispAfiAddress dstPrefix) {
        super(LispCanonicalAddressFormatEnum.SOURCE_DEST, reserved1,
                                                        reserved2, flag, length);
        this.reserved = reserved;
        this.srcMaskLength = srcMaskLength;
        this.dstMaskLength = dstMaskLength;
        this.srcPrefix = srcPrefix;
        this.dstPrefix = dstPrefix;
    }

    /**
     * Obtains source address prefix.
     *
     * @return source address prefix
     */
    public LispAfiAddress getSrcPrefix() {
        return srcPrefix;
    }

    /**
     * Obtains destination address prefix.
     *
     * @return destination address prefix
     */
    public LispAfiAddress getDstPrefix() {
        return dstPrefix;
    }

    /**
     * Obtains source mask length.
     *
     * @return source mask length
     */
    public byte getSrcMaskLength() {
        return srcMaskLength;
    }

    /**
     * Obtains destination mask length.
     *
     * @return destination mask length
     */
    public byte getDstMaskLength() {
        return dstMaskLength;
    }

    /**
     * Obtains reserved value.
     *
     * @return reserved value
     */
    public short getReserved() {
        return reserved;
    }

    @Override
    public int hashCode() {
        return Objects.hash(srcPrefix, dstPrefix, srcMaskLength, dstMaskLength, reserved);
    }

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

        if (obj instanceof LispSourceDestLcafAddress) {
            final LispSourceDestLcafAddress other = (LispSourceDestLcafAddress) obj;
            return Objects.equals(this.srcPrefix, other.srcPrefix) &&
                    Objects.equals(this.dstPrefix, other.dstPrefix) &&
                    Objects.equals(this.srcMaskLength, other.srcMaskLength) &&
                    Objects.equals(this.dstMaskLength, other.dstMaskLength) &&
                    Objects.equals(this.reserved, other.reserved);
        }
        return false;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("source prefix", srcPrefix)
                .add("destination prefix", dstPrefix)
                .add("source mask length", srcMaskLength)
                .add("destination mask length", dstMaskLength)
                .add("reserved", reserved)
                .toString();
    }

    public static final class SourceDestAddressBuilder
            extends LcafAddressBuilder<SourceDestAddressBuilder> {
        private LispAfiAddress srcPrefix;
        private LispAfiAddress dstPrefix;
        private byte srcMaskLength;
        private byte dstMaskLength;
        private short reserved;

        /**
         * Sets source address prefix.
         *
         * @param srcPrefix source prefix
         * @return SourceDestAddressBuilder object
         */
        public SourceDestAddressBuilder withSrcPrefix(LispAfiAddress srcPrefix) {
            this.srcPrefix = srcPrefix;
            return this;
        }

        /**
         * Sets destination address prefix.
         *
         * @param dstPrefix destination prefix
         * @return SourceDestAddressBuilder object
         */
        public SourceDestAddressBuilder withDstPrefix(LispAfiAddress dstPrefix) {
            this.dstPrefix = dstPrefix;
            return this;
        }

        /**
         * Sets source mask length.
         *
         * @param srcMaskLength source mask length
         * @return SourceDestAddressBuilder object
         */
        public SourceDestAddressBuilder withSrcMaskLength(byte srcMaskLength) {
            this.srcMaskLength = srcMaskLength;
            return this;
        }

        /**
         * Sets destination mask length.
         *
         * @param dstMaskLength destination mask length
         * @return SourceDestAddressBuilder object
         */
        public SourceDestAddressBuilder withDstMaskLength(byte dstMaskLength) {
            this.dstMaskLength = dstMaskLength;
            return this;
        }

        /**
         * Sets reserved value.
         *
         * @param reserved reserved field value
         * @return SourceDestAddressBuilder object
         */
        public SourceDestAddressBuilder withReserved(short reserved) {
            this.reserved = reserved;
            return this;
        }

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

            checkNotNull(srcPrefix, "Must specify a source address prefix");
            checkNotNull(dstPrefix, "Must specify a destination address prefix");

            return new LispSourceDestLcafAddress(reserved1, reserved2, flag, length,
                    reserved, srcMaskLength, dstMaskLength, srcPrefix, dstPrefix);
        }
    }

    /**
     * SourceDest LCAF address reader class.
     */
    public static class SourceDestLcafAddressReader
            implements LispAddressReader<LispSourceDestLcafAddress> {

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

            deserializeCommon(byteBuf);

            short reserved = byteBuf.readShort();
            byte srcMaskLength = (byte) byteBuf.readUnsignedByte();
            byte dstMaskLength = (byte) byteBuf.readUnsignedByte();

            LispAfiAddress srcPrefix = new AfiAddressReader().readFrom(byteBuf);
            LispAfiAddress dstPrefix = new AfiAddressReader().readFrom(byteBuf);

            return new SourceDestAddressBuilder()
                    .withReserved(reserved)
                    .withSrcMaskLength(srcMaskLength)
                    .withDstMaskLength(dstMaskLength)
                    .withSrcPrefix(srcPrefix)
                    .withDstPrefix(dstPrefix)
                    .build();
        }
    }

    /**
     * SourceDest LCAF address writer class.
     */
    public static class SourceDestLcafAddressWriter
            implements LispAddressWriter<LispSourceDestLcafAddress> {

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

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

            byteBuf.writeShort(address.getReserved());
            byteBuf.writeByte(address.getSrcMaskLength());
            byteBuf.writeByte(address.getDstMaskLength());
            AfiAddressWriter writer = new AfiAddressWriter();
            writer.writeTo(byteBuf, address.getSrcPrefix());
            writer.writeTo(byteBuf, address.getDstPrefix());

            updateLength(lcafIndex, byteBuf);
        }
    }
}
