/*
 * 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.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.LispNoAddress;
import org.onosproject.lisp.msg.authentication.LispAuthenticationKeyEnum;
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 request message class.
 */
public class DefaultLispInfoRequest extends DefaultLispInfo
        implements LispInfoRequest {

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

    static final InfoRequestWriter WRITER;

    static {
        WRITER = new InfoRequestWriter();
    }

    /**
     * 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
     */
    protected DefaultLispInfoRequest(boolean infoReply, long nonce, short keyId,
                                     short authDataLength, byte[] authData,
                                     int ttl, byte maskLength,
                                     LispAfiAddress eidPrefix) {

        super(infoReply, nonce, keyId, authDataLength, authData, ttl,
              maskLength, eidPrefix);
    }

    @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).toString();
    }

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

        DefaultLispInfoRequest that = (DefaultLispInfoRequest) 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);
    }

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

    @Override
    public void writeTo(ByteBuf byteBuf) throws LispWriterException {
        WRITER.writeTo(byteBuf, this);
    }

    public static final class DefaultInfoRequestBuilder
            implements InfoRequestBuilder {

        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;

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


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

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

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

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

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

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

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

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

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

        @Override
        public LispInfoRequest 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 DefaultLispInfoRequest(infoReply, nonce, keyId,
                                               authDataLength, authData, ttl,
                                               maskLength, eidPrefix)
                            .writeTo(byteBuf);
                } catch (LispWriterException e) {
                    log.warn("Failed to serialize info request", 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 DefaultLispInfoRequest(infoReply, nonce, keyId,
                    authDataLength, authData, ttl, maskLength, eidPrefix);
        }
    }

    /**
     * A LISP message reader for InfoRequest message.
     */
    public static class InfoRequestReader
            implements LispMessageReader<LispInfoRequest> {

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

            LispInfo lispInfo = deserialize(byteBuf);

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

    /**
     * A LISP message writer for InfoRequest message.
     */
    public static final class InfoRequestWriter
            implements LispMessageWriter<LispInfoRequest> {

        @Override
        public void writeTo(ByteBuf byteBuf, LispInfoRequest message)
                throws LispWriterException {

            serialize(byteBuf, message);

            //Fill AFI=0, no address
            new LispAfiAddress.AfiAddressWriter()
                    .writeTo(byteBuf, new LispNoAddress());

        }
    }
}
