/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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.provider.bgp.cfg.impl;

import com.fasterxml.jackson.databind.JsonNode;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onlab.packet.IpAddress;
import org.onosproject.bgp.controller.BgpCfg;
import org.onosproject.bgp.controller.BgpController;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.config.Config.FieldPresence.MANDATORY;
import static org.onosproject.net.config.Config.FieldPresence.OPTIONAL;

/**
 * Configuration object for BGP.
 */
public class BgpAppConfig extends Config<ApplicationId> {
    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    BgpController bgpController;

    BgpCfg bgpConfig = null;

    protected final Logger log = LoggerFactory.getLogger(BgpAppConfig.class);
    public static final String ROUTER_ID = "routerId";
    public static final String LOCAL_AS = "localAs";
    public static final String MAX_SESSION = "maxSession";
    public static final String LS_CAPABILITY = "lsCapability";
    public static final String HOLD_TIME = "holdTime";
    public static final String LARGE_AS_CAPABILITY = "largeAsCapability";
    public static final String FLOW_SPEC_CAPABILITY = "flowSpecCapability";
    public static final String FLOW_SPEC_RPD_CAPABILITY = "flowSpecRpdCapability";
    public static final String EVPN_CAPABILITY = "evpnCapability";

    public static final String BGP_PEER = "bgpPeer";
    public static final String PEER_IP = "peerIp";
    public static final String REMOTE_AS = "remoteAs";
    public static final String PEER_HOLD_TIME = "peerHoldTime";
    public static final String PEER_CONNECT_MODE = "connectMode";
    public static final String PEER_CONNECT_PASSIVE = "passive";
    public static final String PEER_CONNECT_ACTIVE = "active";

    public static final String CONNECTION_TYPE = "connectionType";
    public static final String CONNECTION_TYPE_IPV4 = "IPV4";
    public static final String CONNECTION_TYPE_IPV6 = "IPV6";
    public static final String CONNECTION_TYPE_IPV4_AND_IPV6 = "IPV4_IPV6";

    static final int MAX_SHORT_AS_NUMBER = 65535;
    static final long MAX_LONG_AS_NUMBER = 4294967295L;

    static final int MIN_SESSION_NUMBER = 1;
    static final long MAX_SESSION_NUMBER = 21;

    static final int MIN_HOLDTIME = 0;
    static final long MAX_HOLDTIME = 65535;

    @Override
    public boolean isValid() {
        boolean fields = false;

        this.bgpController = DefaultServiceDirectory.getService(BgpController.class);
        bgpConfig = bgpController.getConfig();

        fields = hasOnlyFields(ROUTER_ID, LOCAL_AS, MAX_SESSION, LS_CAPABILITY,
                               HOLD_TIME, LARGE_AS_CAPABILITY, FLOW_SPEC_CAPABILITY,
                               FLOW_SPEC_RPD_CAPABILITY, BGP_PEER, EVPN_CAPABILITY, CONNECTION_TYPE) &&
                isIpAddress(ROUTER_ID, MANDATORY) && isNumber(LOCAL_AS, MANDATORY) &&
                isNumber(MAX_SESSION, OPTIONAL, MIN_SESSION_NUMBER, MAX_SESSION_NUMBER)
                && isNumber(HOLD_TIME, OPTIONAL, MIN_HOLDTIME, MAX_HOLDTIME) &&
                isBoolean(LS_CAPABILITY, OPTIONAL) && isBoolean(LARGE_AS_CAPABILITY, OPTIONAL) &&
                isString(FLOW_SPEC_CAPABILITY, OPTIONAL) && isBoolean(FLOW_SPEC_RPD_CAPABILITY, OPTIONAL)
                && isBoolean(EVPN_CAPABILITY, OPTIONAL) && isString(CONNECTION_TYPE, OPTIONAL);

        if (!fields) {
            return fields;
        }

        return validateBgpConfiguration();
    }

    /**
     * Returns routerId from the configuration.
     *
     * @return routerId
     */
    public String routerId() {
        return get(ROUTER_ID, null);
    }

    /**
     * Returns localAs number from the configuration.
     *
     * @return local As number
     */
    public int localAs() {
        return Integer.parseInt(get(LOCAL_AS, null));
    }

    /**
     * Returns max session from the configuration.
     *
     * @return max session
     */
    public int maxSession() {
        return Integer.parseInt(get(MAX_SESSION, null));
    }

    /**
     * Returns BGP-LS capability support from the configuration.
     *
     * @return true if BGP-LS capability is set else false
     */
    public boolean lsCapability() {
        return Boolean.parseBoolean(get(LS_CAPABILITY, null));
    }

    /**
     * Returns flow spec route policy distribution capability support from the configuration.
     *
     * @return true if flow spec route policy distribution capability is set otherwise false
     */
    public boolean rpdCapability() {
        return Boolean.parseBoolean(get(FLOW_SPEC_RPD_CAPABILITY, null));
    }

    /**
     * Returns largeAs capability support from the configuration.
     *
     * @return largeAs capability
     */
    public boolean largeAsCapability() {
        return Boolean.parseBoolean(get(LARGE_AS_CAPABILITY, null));
    }

    /**
     * Returns flow specification capability support from the configuration.
     *
     * @return flow specification capability
     */
    public String flowSpecCapability() {
        return get(FLOW_SPEC_CAPABILITY, null);
    }

    /**
     * Returns holdTime of the local node from the configuration.
     *
     * @return holdTime
     */
    public short holdTime() {
        return Short.parseShort(get(HOLD_TIME, null));
    }

    /**
     * Returns BGP connection type from the configuration.
     *
     * @return BGP connection type
     */
    public String connectionType() {
        return get(CONNECTION_TYPE, null);
    }

    /**
     * Validates the BGP connection type.
     *
     * @return true if valid else false
     */
    public boolean validateConnectionType() {
        if (connectionType() != null) {
            String connectionType = connectionType();
            if (!connectionType.equals(CONNECTION_TYPE_IPV4) && !connectionType.equals(CONNECTION_TYPE_IPV6)
                    && !connectionType.equals(CONNECTION_TYPE_IPV4_AND_IPV6)) {
                log.error("Connection Type is invalid");
                return false;
            }
        }
        log.debug("Connection Type is valid");
        return true;
    }

    /**
     * Validates the flow specification capability.
     *
     * @return true if valid else false
     */
    public boolean validateFlowSpec() {
        if (flowSpecCapability() != null) {
            String flowSpec = flowSpecCapability();
            if ((!flowSpec.equals("IPV4")) && (!flowSpec.equals("VPNV4")) && (!flowSpec.equals("IPV4_VPNV4"))) {
                log.debug("Flow specification capabality is false");
                return false;
            }
        }
        log.debug("Flow specification capabality is true");
        return true;
    }

    /**
     * Returns evpn capability support from the configuration.
     *
     * @return evpn capability
     */
    public boolean evpnCapability() {
        return Boolean.parseBoolean(get(EVPN_CAPABILITY, null));
    }

    /**
     * Validates the hold time value.
     *
     * @return true if valid else false
     */
    public boolean validateHoldTime() {
        if (holdTime() != 0) {
            short holdTime = holdTime();
            if ((holdTime == 1) || (holdTime == 2)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Validates the Bgp local and peer configuration.
     *
     * @return true if valid else false
     */
    public boolean validateBgpConfiguration() {

        if (!validateLocalAs()) {
            return false;
        }

        if (!validateRouterId()) {
            return false;
        }

        if (!validateBgpPeers()) {
            return false;
        }

        if (!validateFlowSpec()) {
            return false;
        }

        if (!validateHoldTime()) {
            return false;
        }

        if (!validateConnectionType()) {
            return false;
        }
        return true;
    }

    /**
     * Validates the Bgp As number.
     *
     * @return true if valid else false
     */
    public boolean validateLocalAs() {

        long localAs = 0;
        localAs = localAs();

        if (largeAsCapability()) {

            if (localAs == 0 || localAs >= MAX_LONG_AS_NUMBER) {
                return false;
            }
        } else {
            if (localAs == 0 || localAs >= MAX_SHORT_AS_NUMBER) {
                return false;
            }
        }

        return true;
    }

    /**
     * Validates the Bgp peer As number.
     *
     * @param remoteAs remote As number
     * @return true if valid else false
     */
    public boolean validateRemoteAs(long remoteAs) {
        if (largeAsCapability()) {

            if (remoteAs == 0 || remoteAs >= MAX_LONG_AS_NUMBER) {
                return false;
            }
        } else {
            if (remoteAs == 0 || remoteAs >= MAX_SHORT_AS_NUMBER) {
                return false;
            }
        }
        return true;
    }

    /**
     * Validates the Bgp Router ID configuration.
     *
     * @return true if valid else false
     */
    public boolean validateRouterId() {
        String routerId = routerId();
        // TODO: router ID validation
        return true;
    }

    /**
     * Validates the Bgp peer holdTime.
     *
     * @param remoteAs remote As number
     * @return true if valid else false
     */
    public boolean validatePeerHoldTime(long remoteAs) {
        //TODO:Validate it later..
        return true;
    }

    /**
     * Validates the Bgp peer configuration.
     *
     * @return true if valid else false
     */
    public boolean validateBgpPeers() {
        List<BgpPeerConfig> nodes;
        String connectMode;

        nodes = bgpPeer();
        for (int i = 0; i < nodes.size(); i++) {
            connectMode = nodes.get(i).connectMode();
            if ((IpAddress.valueOf(nodes.get(i).hostname()) == null) ||
                    !validateRemoteAs(nodes.get(i).asNumber()) ||
                    !validatePeerHoldTime(nodes.get(i).holdTime()) ||
                    !(connectMode.equals(PEER_CONNECT_ACTIVE) || connectMode.equals(PEER_CONNECT_PASSIVE))) {
                log.debug("BGP peer configration false");
                return false;
            }
        }
        log.debug("BGP peer configration true");
        return true;
    }

    /**
     * Returns the set of nodes read from network config.
     *
     * @return list of BgpPeerConfig or null
     */
    public List<BgpPeerConfig> bgpPeer() {
        List<BgpPeerConfig> nodes = new ArrayList<BgpPeerConfig>();
        JsonNode jsonNodes = object.get(BGP_PEER);
        if (jsonNodes == null) {
            return null;
        }

        jsonNodes.forEach(jsonNode -> nodes.add(new BgpPeerConfig(
                jsonNode.path(PEER_IP).asText(),
                jsonNode.path(REMOTE_AS).asInt(),
                jsonNode.path(PEER_HOLD_TIME).asInt(),
                jsonNode.path(PEER_CONNECT_MODE).asText())));

        return nodes;
    }

    /**
     * Configuration for Bgp peer nodes.
     */
    public static class BgpPeerConfig {

        private final String hostname;
        private final int asNumber;
        private final short holdTime;
        private final String connectMode;

        public BgpPeerConfig(String hostname, int asNumber, int holdTime, String connectMode) {
            this.hostname = checkNotNull(hostname);
            this.asNumber = asNumber;
            this.holdTime = (short) holdTime;
            this.connectMode = connectMode;
        }

        /**
         * Returns hostname of the peer node.
         *
         * @return hostname
         */
        public String hostname() {
            return this.hostname;
        }

        /**
         * Returns asNumber if peer.
         *
         * @return asNumber
         */
        public int asNumber() {
            return this.asNumber;
        }

        /**
         * Returns holdTime of the peer node.
         *
         * @return holdTime
         */
        public short holdTime() {
            return this.holdTime;
        }

        /**
         * Returns connection mode for the peer node.
         *
         * @return active or passive connection
         */
        public String connectMode() {
            return this.connectMode;
        }
    }
}
