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

/**
 * Source/Dest key type LCAF address class.
 * <p>
 * Source destination key type is defined in draft-ietf-lisp-lcaf-20
 * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-20#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/dest 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 {

            LispLcafAddress lcafAddress = LispLcafAddress.deserializeCommon(byteBuf);

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

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

            return new SourceDestAddressBuilder()
                    .withReserved1(lcafAddress.getReserved1())
                    .withReserved2(lcafAddress.getReserved2())
                    .withFlag(lcafAddress.getFlag())
                    .withLength(lcafAddress.getLength())
                    .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 {

            LispLcafAddress.serializeCommon(byteBuf, address);

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