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

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Sets;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.EncapsulationType;
import org.onosproject.net.config.Config;

import java.util.Set;

/**
 * Represents the VPLS application configuration.
 */
public class VplsAppConfig extends Config<ApplicationId> {
    private static final String VPLS = "vplsList";
    private static final String NAME = "name";
    private static final String INTERFACE = "interfaces";
    private static final String ENCAPSULATION = "encapsulation";

    /**
     * Returns a set of configured VPLSs.
     *
     * @return set of VPLSs
     */
    public Set<VplsConfig> vplss() {
        Set<VplsConfig> vplss = Sets.newHashSet();

        JsonNode vplsNode = object.get(VPLS);

        if (vplsNode == null) {
            return vplss;
        }

        vplsNode.forEach(jsonNode -> {
            String name = jsonNode.get(NAME).asText();

            Set<String> ifaces = Sets.newHashSet();
            JsonNode vplsIfaces = jsonNode.path(INTERFACE);
            if (vplsIfaces.toString().isEmpty()) {
                vplsIfaces = ((ObjectNode) jsonNode).putArray(INTERFACE);
            }
            vplsIfaces.forEach(ifacesNode -> ifaces.add(ifacesNode.asText()));

            String encap = null;
            if (jsonNode.hasNonNull(ENCAPSULATION)) {
                encap = jsonNode.get(ENCAPSULATION).asText();
            }
            vplss.add(new VplsConfig(name,
                                     ifaces,
                                     EncapsulationType.enumFromString(encap)));
        });

        return vplss;
    }

    /**
     * Returns the VPLS configuration given a VPLS name.
     *
     * @param name the name of the VPLS
     * @return the VPLS configuration if it exists; null otherwise
     */
    public VplsConfig getVplsWithName(String name) {
        return vplss().stream()
                      .filter(vpls -> vpls.name().equals(name))
                      .findFirst()
                      .orElse(null);
    }

    /**
     * Adds a VPLS to the configuration.
     *
     * @param vpls the name of the VPLS
     */
    public void addVpls(VplsConfig vpls) {
        ObjectNode vplsNode = JsonNodeFactory.instance.objectNode();

        vplsNode.put(NAME, vpls.name());

        ArrayNode ifacesNode = vplsNode.putArray(INTERFACE);
        vpls.ifaces().forEach(ifacesNode::add);

        vplsNode.put(ENCAPSULATION, vpls.encap().toString());

        ArrayNode vplsArray = vplss().isEmpty() ?
                initVplsConfiguration() : (ArrayNode) object.get(VPLS);
        vplsArray.add(vplsNode);
    }

    /**
     * Removes a VPLS from the configuration.
     *
     * @param vplsName the vplsName of the VPLS to be removed
     */
    public void removeVpls(String vplsName) {
        ArrayNode configuredVpls = (ArrayNode) object.get(VPLS);

        for (int i = 0; i < configuredVpls.size(); i++) {
            if (configuredVpls.get(i).hasNonNull(NAME) &&
                    configuredVpls.get(i).get(NAME).asText().equals(vplsName)) {
                configuredVpls.remove(i);
                return;
            }
        }
    }

    /**
     * Finds a VPLS with a given network interface.
     *
     * @param iface the network interface
     * @return the VPLS if found; null otherwise
     */
    public VplsConfig vplsFromIface(String iface) {
        for (VplsConfig vpls : vplss()) {
            if (vpls.isAttached(iface)) {
                return vpls;
            }
        }
        return null;
    }

    /**
     * Adds a network interface to a VPLS.
     *
     * @param vplsName the vplsName of the VPLS
     * @param iface the network interface to be added
     */
    public void addIface(String vplsName, String iface) {
        JsonNode vplsNodes = object.get(VPLS);
        vplsNodes.forEach(vplsNode -> {
            if (hasNamedNode(vplsNode, vplsName)) {
                ArrayNode ifacesNode = (ArrayNode) vplsNode.get(INTERFACE);
                for (int i = 0; i < ifacesNode.size(); i++) {
                    if (ifacesNode.get(i).asText().equals(iface)) {
                        return; // Interface already exists.
                    }
                }
                ifacesNode.add(iface);
            }
        });
    }

    /**
     * Removes a network interface from a VPLS.
     *
     * @param name the name of the VPLS
     * @param iface the network interface to be removed
     */
    public void removeIface(VplsConfig name, String iface) {
        JsonNode vplsNodes = object.get(VPLS);
        vplsNodes.forEach(vplsNode -> {
            if (hasNamedNode(vplsNode, name.name())) {
                ArrayNode ifacesNode = (ArrayNode) vplsNode.get(INTERFACE);
                for (int i = 0; i < ifacesNode.size(); i++) {
                    if (ifacesNode.get(i).asText().equals(iface)) {
                        ifacesNode.remove(i);
                        return;
                    }
                }
            }
        });
    }

    /**
     * Activate, deactivates, sets the encapsulation type for a given VPLS.
     *
     * @param vplsName the vplsName of the VPLS
     * @param encap the encapsulation type, if set
     */
    public void setEncap(String vplsName, EncapsulationType encap) {
        JsonNode vplsNodes = object.get(VPLS);
        vplsNodes.forEach(vplsNode -> {
            if (hasNamedNode(vplsNode, vplsName)) {
                ((ObjectNode) vplsNode).put(ENCAPSULATION, encap.toString());
            }
        });
    }

    /**
     * States if a JSON node has a "name" attribute and if the value is equal to
     * the name given.
     *
     * @param jsonNode the JSON node
     * @param name the node name
     * @return true if the JSON node has a "name" attribute with value equal to
     * the name given; false otherwise
     */
    private boolean hasNamedNode(JsonNode jsonNode, String name) {
        return jsonNode.hasNonNull(NAME) &&
                jsonNode.get(NAME).asText().equals(name);
    }

    /**
     * Creates an empty VPLS configuration.
     *
     * @return empty ArrayNode to store the VPLS configuration
     */
    private ArrayNode initVplsConfiguration() {
        return object.putArray(VPLS);
    }
}
