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

import com.google.common.collect.Lists;
import org.onosproject.lisp.msg.protocols.DefaultLispEncapsulatedControl.DefaultEcmBuilder;
import org.onosproject.lisp.msg.protocols.DefaultLispMapReply.DefaultReplyBuilder;
import org.onosproject.lisp.msg.protocols.LispEncapsulatedControl;
import org.onosproject.lisp.msg.protocols.LispEncapsulatedControl.EcmBuilder;
import org.onosproject.lisp.msg.protocols.LispLocatorRecord;
import org.onosproject.lisp.msg.protocols.LispMapRecord;
import org.onosproject.lisp.msg.protocols.LispMapReply.ReplyBuilder;
import org.onosproject.lisp.msg.protocols.LispMapRequest;
import org.onosproject.lisp.msg.protocols.LispMapReply;
import org.onosproject.lisp.msg.protocols.LispMessage;
import org.onosproject.lisp.msg.types.LispAfiAddress;
import org.onosproject.lisp.msg.types.LispIpAddress;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.List;

/**
 * LISP map resolver class.
 * Handles map-request message and acknowledges with map-reply message.
 */
public final class LispMapResolver {

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

    private static final int ECM_DST_PORT = 4342;
    private static final String NO_ITR_RLOCS_MSG =
                                "No ITR RLOC is found, cannot respond to ITR.";
    private static final String NO_ETR_RLOCS_MSG =
                                "No ETR RLOC is found, cannot relay to ETR.";
    private static final String NO_MAP_INFO_MSG  = "Map information is not found.";

    private LispMappingDatabase mapDb = LispMappingDatabase.getInstance();

    // non-instantiable (except for our Singleton)
    private LispMapResolver() {
    }

    static LispMapResolver getInstance() {
        return SingletonHelper.INSTANCE;
    }

    /**
     * Handles encapsulated control message and replies with map-reply message.
     *
     * @param message encapsulated control message
     * @return map-reply message
     */
    List<LispMessage> processMapRequest(LispMessage message) {

        LispEncapsulatedControl ecm = (LispEncapsulatedControl) message;
        LispMapRequest request = (LispMapRequest) ecm.getControlMessage();

        List<LispMapRecord> mapReplyRecords =
                mapDb.getMapRecordByEidRecords(request.getEids(), true);

        List<LispMapRecord> mapRequestRecords =
                mapDb.getMapRecordByEidRecords(request.getEids(), false);

        if (mapReplyRecords.size() + mapRequestRecords.size() == 0) {

            // TODO: need to generate map-reply with configured native-forward action
            log.warn(NO_MAP_INFO_MSG);

        } else {

            if (mapReplyRecords.size() > 0) {

                List<LispMessage> mapReplies = Lists.newArrayList();

                // build map-reply message based on map-request from ITR
                ReplyBuilder replyBuilder = initMapReplyBuilder(request);
                replyBuilder.withMapRecords(mapReplyRecords);

                List<InetSocketAddress> addresses =
                                        getItrAddresses(request.getItrRlocs(),
                                                ecm.innerUdp().getSourcePort());

                addresses.forEach(address -> {
                    if (address != null) {
                        LispMapReply reply = replyBuilder.build();
                        reply.configSender(address);
                        mapReplies.add(reply);
                    } else {
                        log.warn(NO_ITR_RLOCS_MSG);
                    }
                });

                return mapReplies;
            }

            if (mapRequestRecords.size() > 0) {

                List<LispMessage> ecms = Lists.newArrayList();

                // re-encapsulate encapsulated control message from ITR
                List<InetSocketAddress> addresses =
                                getEtrAddresses(mapRequestRecords, ECM_DST_PORT);

                addresses.forEach(address -> {
                    if (address != null) {
                        LispEncapsulatedControl reencapEcm = cloneEcm(ecm);
                        reencapEcm.configSender(address);
                        ecms.add(reencapEcm);
                    } else {
                        log.warn(NO_ETR_RLOCS_MSG);
                    }
                });

                return ecms;
            }
        }
        return null;
    }

    /**
     * Initializes MapReply builder without specifying map records.
     *
     * @param request received map request from ITR
     * @return initialized MapReply builder
     */
    private ReplyBuilder initMapReplyBuilder(LispMapRequest request) {
        ReplyBuilder replyBuilder = new DefaultReplyBuilder();
        replyBuilder.withNonce(request.getNonce());
        replyBuilder.withIsEtr(false);
        replyBuilder.withIsSecurity(false);
        replyBuilder.withIsProbe(request.isProbe());

        return replyBuilder;
    }

    /**
     * Clones ECM from original ECM.
     *
     * @param ecm original ECM
     * @return cloned ECM
     */
    private LispEncapsulatedControl cloneEcm(LispEncapsulatedControl ecm) {
        EcmBuilder ecmBuilder = new DefaultEcmBuilder();
        ecmBuilder.innerLispMessage(ecm.getControlMessage());
        ecmBuilder.isSecurity(ecm.isSecurity());
        ecmBuilder.innerIpHeader(ecm.innerIpHeader());
        ecmBuilder.innerUdpHeader(ecm.innerUdp());

        return ecmBuilder.build();
    }

    /**
     * Obtains a collection of valid ITR addresses with a port number specified.
     * These addresses will be used to acknowledge map-reply to ITR.
     *
     * @param itrRlocs a collection of ITR RLOCs
     * @param port     port number
     * @return a collection of valid ITR addresses with a port number specified
     */
    private List<InetSocketAddress> getItrAddresses(List<LispAfiAddress> itrRlocs,
                                                    int port) {
        List<InetSocketAddress> addresses = Lists.newArrayList();
        for (LispAfiAddress itrRloc : itrRlocs) {
            addresses.add(new InetSocketAddress(((LispIpAddress)
                    itrRloc).getAddress().toInetAddress(), port));
        }
        return addresses;
    }

    /**
     * Obtains a collection of valid ETR addresses with a port number specified.
     * These addresses will be used to relay map-request to ETR.
     *
     * @param mapRecords a collection of map records
     * @param port       port number
     * @return a collection of valid ETR addresses with a port number specified
     */
    private List<InetSocketAddress> getEtrAddresses(List<LispMapRecord> mapRecords,
                                                    int port) {
        List<InetSocketAddress> addresses = Lists.newArrayList();
        for (LispMapRecord mapRecord : mapRecords) {

            // we only select the first locator record in all cases...
            LispLocatorRecord locatorRecord = mapRecord.getLocators().get(0);
            if (locatorRecord != null) {
                addresses.add(new InetSocketAddress(((LispIpAddress)
                                locatorRecord.getLocatorAfi()).getAddress()
                                                    .toInetAddress(), port));
            }
        }
        return addresses;
    }

    /**
     * Prevents object instantiation from external.
     */
    private static final class SingletonHelper {
        private static final String ILLEGAL_ACCESS_MSG = "Should not instantiate this class.";
        private static final LispMapResolver INSTANCE = new LispMapResolver();

        private SingletonHelper() {
            throw new IllegalAccessError(ILLEGAL_ACCESS_MSG);
        }
    }
}
