/*
 * 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 org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressReader;
import org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;

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);
        }
    }
}
