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

import com.google.common.base.Objects;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.onosproject.lisp.msg.authentication.LispAuthenticationFactory;
import org.onosproject.lisp.msg.authentication.LispAuthenticationKeyEnum;
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;
import org.onosproject.lisp.msg.types.LispNatLcafAddress;
import org.onosproject.lisp.msg.types.LispNatLcafAddress.NatLcafAddressWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

import static com.google.common.base.MoreObjects.toStringHelper;
import static org.onosproject.lisp.msg.authentication.LispAuthenticationKeyEnum.valueOf;

/**
 * Default LISP info reply message class.
 */
public final class DefaultLispInfoReply extends DefaultLispInfo implements LispInfoReply {

    private static final Logger log = LoggerFactory.getLogger(DefaultLispInfoReply.class);

    private final LispNatLcafAddress natLcafAddress;

    /**
     * A private constructor that protects object instantiation from external.
     *
     * @param infoReply      info reply flag
     * @param nonce          nonce
     * @param keyId          key identifier
     * @param authDataLength authentication data length
     * @param authData       authentication data
     * @param ttl            Time-To-Live value
     * @param maskLength     EID prefix mask length
     * @param eidPrefix      EID prefix
     * @param natLcafAddress NAT LCAF address
     */
    protected DefaultLispInfoReply(boolean infoReply, long nonce, short keyId, short authDataLength,
                                   byte[] authData, int ttl, byte maskLength,
                                   LispAfiAddress eidPrefix, LispNatLcafAddress natLcafAddress) {
        super(infoReply, nonce, keyId, authDataLength, authData, ttl, maskLength, eidPrefix);
        this.natLcafAddress = natLcafAddress;
    }

    @Override
    public LispNatLcafAddress getNatLcafAddress() {
        return natLcafAddress;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("type", getType())
                .add("nonce", nonce)
                .add("keyId", keyId)
                .add("authentication data length", authDataLength)
                .add("authentication data", authData)
                .add("TTL", ttl)
                .add("EID mask length", maskLength)
                .add("EID prefix", eidPrefix)
                .add("NAT LCAF address", natLcafAddress).toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        DefaultLispInfoReply that = (DefaultLispInfoReply) o;
        return Objects.equal(nonce, that.nonce) &&
                Objects.equal(keyId, that.keyId) &&
                Objects.equal(authDataLength, that.authDataLength) &&
                Arrays.equals(authData, that.authData) &&
                Objects.equal(ttl, that.ttl) &&
                Objects.equal(maskLength, that.maskLength) &&
                Objects.equal(eidPrefix, that.eidPrefix) &&
                Objects.equal(natLcafAddress, that.natLcafAddress);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(nonce, keyId, authDataLength, ttl, maskLength,
                eidPrefix, natLcafAddress) + Arrays.hashCode(authData);
    }

    public static final class DefaultInfoReplyBuilder implements InfoReplyBuilder {

        private boolean infoReply;
        private long nonce;
        private short keyId;
        private short authDataLength;
        private byte[] authData;
        private String authKey;
        private int ttl;
        private byte maskLength;
        private LispAfiAddress eidPrefix;
        private LispNatLcafAddress natLcafAddress;

        @Override
        public LispType getType() {
            return LispType.LISP_INFO;
        }


        @Override
        public InfoReplyBuilder withIsInfoReply(boolean infoReply) {
            this.infoReply = infoReply;
            return this;
        }

        @Override
        public InfoReplyBuilder withNonce(long nonce) {
            this.nonce = nonce;
            return this;
        }

        @Override
        public InfoReplyBuilder withAuthDataLength(short authDataLength) {
            this.authDataLength = authDataLength;
            return this;
        }

        @Override
        public InfoReplyBuilder withKeyId(short keyId) {
            this.keyId = keyId;
            return this;
        }

        @Override
        public InfoReplyBuilder withAuthData(byte[] authenticationData) {
            if (authenticationData != null) {
                this.authData = authenticationData;
            }
            return this;
        }

        @Override
        public InfoReplyBuilder withAuthKey(String key) {
            this.authKey = key;
            return this;
        }

        @Override
        public InfoReplyBuilder withTtl(int ttl) {
            this.ttl = ttl;
            return this;
        }

        @Override
        public InfoReplyBuilder withMaskLength(byte maskLength) {
            this.maskLength = maskLength;
            return this;
        }

        @Override
        public InfoReplyBuilder withEidPrefix(LispAfiAddress eidPrefix) {
            this.eidPrefix = eidPrefix;
            return this;
        }


        @Override
        public InfoReplyBuilder withNatLcafAddress(LispNatLcafAddress natLcafAddress) {
            this.natLcafAddress = natLcafAddress;
            return this;
        }

        @Override
        public LispInfoReply build() {

            // if authentication data is not specified, we will calculate it
            if (authData == null) {
                LispAuthenticationFactory factory = LispAuthenticationFactory.getInstance();

                authDataLength = LispAuthenticationKeyEnum.valueOf(keyId).getHashLength();
                byte[] tmpAuthData = new byte[authDataLength];
                Arrays.fill(tmpAuthData, (byte) 0);
                authData = tmpAuthData;

                ByteBuf byteBuf = Unpooled.buffer();
                try {
                    new DefaultLispInfoReply(infoReply, nonce, keyId, authDataLength,
                            authData, ttl, maskLength, eidPrefix, natLcafAddress).writeTo(byteBuf);
                } catch (LispWriterException e) {
                    log.warn("Failed to serialize info reply", e);
                }

                byte[] bytes = new byte[byteBuf.readableBytes()];
                byteBuf.readBytes(bytes);

                if (authKey == null) {
                    log.warn("Must specify authentication key");
                }

                authData = factory.createAuthenticationData(valueOf(keyId), authKey, bytes);
            }

            return new DefaultLispInfoReply(infoReply, nonce, keyId, authDataLength,
                    authData, ttl, maskLength, eidPrefix, natLcafAddress);
        }
    }

    /**
     * A LISP message reader for InfoReply message.
     */
    public static final class InfoReplyReader implements LispMessageReader<LispInfoReply> {

        @Override
        public LispInfoReply readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
            LispInfo lispInfo = DefaultLispInfo.deserialize(byteBuf);
            LispNatLcafAddress natLcafAddress = new LispNatLcafAddress.NatLcafAddressReader().readFrom(byteBuf);

            return new DefaultInfoReplyBuilder()
                    .withIsInfoReply(lispInfo.isInfoReply())
                    .withNonce(lispInfo.getNonce())
                    .withKeyId(lispInfo.getKeyId())
                    .withAuthDataLength(lispInfo.getAuthDataLength())
                    .withAuthData(lispInfo.getAuthData())
                    .withTtl(lispInfo.getTtl())
                    .withMaskLength(lispInfo.getMaskLength())
                    .withEidPrefix(lispInfo.getPrefix())
                    .withNatLcafAddress(natLcafAddress).build();
        }
    }

    public static final class InfoReplyWriter implements LispMessageWriter<LispInfoReply> {

        @Override
        public void writeTo(ByteBuf byteBuf, LispInfoReply message) throws LispWriterException {
            DefaultLispInfo.serialize(byteBuf, message);

            // NAT LCAF address
            NatLcafAddressWriter writer = new NatLcafAddressWriter();
            writer.writeTo(byteBuf, message.getNatLcafAddress());
        }
    }
}
