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

/**
 * Multicast group membership type LCAF address class.
 * <p>
 * Multicast group membership type is defined in draft-ietf-lisp-lcaf-22
 * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-22#page-15
 * <p>
 * <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 = 9    |     Rsvd2     |             Length            |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                         Instance-ID                           |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |            Reserved           | Source MaskLen| Group MaskLen |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |              AFI = x          |   Source/Subnet Address  ...  |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |              AFI = x          |       Group Address  ...      |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * }</pre>
 */
public final class LispMulticastLcafAddress extends LispLcafAddress {

    private final int instanceId;
    private final byte srcMaskLength;
    private final byte grpMaskLength;
    private final LispAfiAddress srcAddress;
    private final LispAfiAddress grpAddress;

    /**
     * Initializes multicast type LCAF address.
     *
     * @param instanceId    instance identifier
     * @param srcMaskLength  source mask length
     * @param grpMaskLength group mask length
     * @param srcAddress    source address
     * @param grpAddress    group address
     */
    private LispMulticastLcafAddress(int instanceId, byte srcMaskLength,
                                     byte grpMaskLength, LispAfiAddress srcAddress,
                                     LispAfiAddress grpAddress) {
        super(LispCanonicalAddressFormatEnum.MULTICAST);
        this.instanceId = instanceId;
        this.srcMaskLength = srcMaskLength;
        this.grpMaskLength = grpMaskLength;
        this.srcAddress = srcAddress;
        this.grpAddress = grpAddress;
    }

    /**
     * Obtains instance identifier.
     *
     * @return instance identifier
     */
    public int getInstanceId() {
        return instanceId;
    }

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

    /**
     * Obtains group mask length.
     *
     * @return group mask length
     */
    public byte getGrpMaskLength() {
        return grpMaskLength;
    }

    /**
     * Obtains source address.
     *
     * @return source address
     */
    public LispAfiAddress getSrcAddress() {
        return srcAddress;
    }

    /**
     * Obtains group address.
     *
     * @return group address
     */
    public LispAfiAddress getGrpAddress() {
        return grpAddress;
    }

    @Override
    public int hashCode() {
        return Objects.hash(instanceId, srcMaskLength, grpMaskLength,
                srcAddress, grpAddress);
    }

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

        if (obj instanceof LispMulticastLcafAddress) {
            final LispMulticastLcafAddress other = (LispMulticastLcafAddress) obj;
            return Objects.equals(this.instanceId, other.instanceId) &&
                    Objects.equals(this.srcMaskLength, other.srcMaskLength) &&
                    Objects.equals(this.grpMaskLength, other.grpMaskLength) &&
                    Objects.equals(this.srcAddress, other.srcAddress) &&
                    Objects.equals(this.grpAddress, other.grpAddress);

        }
        return false;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("instance ID", instanceId)
                .add("source mask length", srcMaskLength)
                .add("group mask length", grpMaskLength)
                .add("source address", srcAddress)
                .add("group address", grpAddress)
                .toString();
    }

    public static final class MulticastAddressBuilder
                        extends LcafAddressBuilder<MulticastAddressBuilder> {
        private int instanceId;
        private byte srcMaskLength;
        private byte grpMaskLength;
        private LispAfiAddress srcAddress;
        private LispAfiAddress grpAddress;

        /**
         * Sets instance identifier.
         *
         * @param instanceId instance identifier
         * @return MulticastAddressBuilder object
         */
        public MulticastAddressBuilder withInstanceId(int instanceId) {
            this.instanceId = instanceId;
            return this;
        }

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

        /**
         * Sets group mask length.
         *
         * @param grpMaskLength group mask length
         * @return MulticastAddressBuilder object
         */
        public MulticastAddressBuilder withGrpMaskLength(byte grpMaskLength) {
            this.grpMaskLength = grpMaskLength;
            return this;
        }

        /**
         * Sets source address.
         *
         * @param srcAddress source address
         * @return MulticastAddressBuilder object
         */
        public MulticastAddressBuilder withSrcAddress(LispAfiAddress srcAddress) {
            this.srcAddress = srcAddress;
            return this;
        }

        /**
         * Sets group address.
         *
         * @param grpAddress group address
         * @return MulticastAddressBuilder object
         */
        public MulticastAddressBuilder withGrpAddress(LispAfiAddress grpAddress) {
            this.grpAddress = grpAddress;
            return this;
        }

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

            checkNotNull(srcAddress, "Must specify a source address");
            checkNotNull(grpAddress, "Must specify a group address");

            return new LispMulticastLcafAddress(instanceId, srcMaskLength,
                                        grpMaskLength, srcAddress, grpAddress);
        }
    }

    /**
     * Multicast LCAF address reader class.
     */
    public static class MulticastLcafAddressReader
                        implements LispAddressReader<LispMulticastLcafAddress> {

        private static final int RESERVED_SKIP_LENGTH = 2;

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

            LispLcafAddress.deserializeCommon(byteBuf);

            int instanceId = (int) byteBuf.readUnsignedInt();
            byteBuf.skipBytes(RESERVED_SKIP_LENGTH);
            byte srcMaskLength = (byte) byteBuf.readUnsignedByte();
            byte grpMaskLength = (byte) byteBuf.readUnsignedByte();
            LispAfiAddress srcAddress = new AfiAddressReader().readFrom(byteBuf);
            LispAfiAddress grpAddress = new AfiAddressReader().readFrom(byteBuf);

            return new MulticastAddressBuilder()
                            .withInstanceId(instanceId)
                            .withSrcMaskLength(srcMaskLength)
                            .withGrpMaskLength(grpMaskLength)
                            .withSrcAddress(srcAddress)
                            .withGrpAddress(grpAddress)
                            .build();
        }
    }

    /**
     * Multicast LCAF address writer class.
     */
    public static class MulticastLcafAddressWriter
                        implements LispAddressWriter<LispMulticastLcafAddress> {

        private static final int UNUSED_ZERO = 0;

        @Override
        public void writeTo(ByteBuf byteBuf, LispMulticastLcafAddress address)
                                                    throws LispWriterException {
            int lcafIndex = byteBuf.writerIndex();
            LispLcafAddress.serializeCommon(byteBuf, address);

            // instance identifier
            byteBuf.writeInt(address.getInstanceId());

            // reserved field
            byteBuf.writeByte(UNUSED_ZERO);
            byteBuf.writeByte(UNUSED_ZERO);

            // source mask length
            byteBuf.writeByte(address.getSrcMaskLength());

            // group mask length
            byteBuf.writeByte(address.getGrpMaskLength());

            // source address
            AfiAddressWriter srcWriter = new AfiAddressWriter();
            srcWriter.writeTo(byteBuf, address.getSrcAddress());

            // group address
            AfiAddressWriter grpWriter = new AfiAddressWriter();
            grpWriter.writeTo(byteBuf, address.getGrpAddress());

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