/*
 * Copyright 2016 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.drivers.oplink;

import com.google.common.collect.ImmutableList;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.onosproject.drivers.utilities.XmlConfigParser;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.netconf.DatastoreId;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;

import java.io.IOException;
import java.util.List;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Netconf utility for oplink netconf drivers.
 */
public final class OplinkNetconfUtility {

    // public used nodes
    public static final String CFG_MODE_MERGE = "merge";
    public static final String CFG_MODE_REMOVE = "remove";
    public static final String KEY_XMLNS = "xmlns=\"http://com/att/device\"";
    public static final String KEY_DATA = "data";
    public static final String KEY_OPENOPTICALDEV = "open-optical-device";
    public static final String KEY_CONNS = "connections";
    public static final String KEY_CONNID = "connection-id";
    public static final String KEY_PORTS = "ports";
    public static final String KEY_PORTID = "port-id";
    public static final String KEY_PORT = "port";
    public static final String KEY_PORTDIRECT = "port-direction";
    public static final String KEY_CHATT = "attenuation";
    public static final String KEY_DATA_CONNS = String.format("%s.%s.%s", KEY_DATA, KEY_OPENOPTICALDEV, KEY_CONNS);
    public static final String KEY_DATA_PORTS = String.format("%s.%s.%s", KEY_DATA, KEY_OPENOPTICALDEV, KEY_PORTS);
    public static final String KEY_OPENOPTICALDEV_XMLNS = String.format("%s %s", KEY_OPENOPTICALDEV, KEY_XMLNS);

    private OplinkNetconfUtility() {
    }

    /**
     * Retrieves session reply information for get operation.
     *
     * @param handler parent driver handler
     * @param filter the filter string of xml content
     * @return the reply string
     */
    public static String netconfGet(DriverHandler handler, String filter) {
        NetconfController controller = checkNotNull(handler.get(NetconfController.class));
        NetconfSession session = controller.getNetconfDevice(handler.data().deviceId()).getSession();
        String reply;
        try {
            reply = session.get(filter, null);
        } catch (IOException e) {
            throw new RuntimeException(new NetconfException("Failed to retrieve configuration.", e));
        }
        return reply;
    }

    /**
     * Retrieves session reply information for get config operation.
     *
     * @param handler parent driver handler
     * @param filter the filter string of xml content
     * @return the reply string
     */
    public static String netconfGetConfig(DriverHandler handler, String filter) {
        NetconfController controller = checkNotNull(handler.get(NetconfController.class));
        NetconfSession session = controller.getNetconfDevice(handler.data().deviceId()).getSession();
        String reply;
        try {
            reply = session.getConfig(DatastoreId.RUNNING, filter);
        } catch (IOException e) {
            throw new RuntimeException(new NetconfException("Failed to retrieve configuration.", e));
        }
        return reply;
    }

    /**
     * Retrieves session reply information for edit config operation.
     *
     * @param handler parent driver handler
     * @param mode selected mode to change the configuration
     * @param cfg the new configuration to be set
     * @return the reply string
     */
    public static boolean netconfEditConfig(DriverHandler handler, String mode, String cfg) {
        NetconfController controller = checkNotNull(handler.get(NetconfController.class));
        NetconfSession session = controller.getNetconfDevice(handler.data().deviceId()).getSession();
        boolean reply = false;
        try {
            reply = session.editConfig(DatastoreId.RUNNING, mode, cfg);
        } catch (IOException e) {
            throw new RuntimeException(new NetconfException("Failed to edit configuration.", e));
        }
        return reply;
    }

    /**
     * Retrieves specified node hierarchical configuration from the xml information.
     *
     * @param content the xml information
     * @param key the configuration key node
     * @return the hierarchical configuration, null if exception happens
     */
    public static HierarchicalConfiguration configAt(String content, String key) {
        HierarchicalConfiguration info;
        try {
            HierarchicalConfiguration cfg = XmlConfigParser.loadXmlString(content);
            info = cfg.configurationAt(key);
        } catch (Exception e) {
            // Accept null for information polling
            return null;
        }
        return info;
    }

    /**
     * Retrieves specified node hierarchical configurations from the xml information.
     *
     * @param content the xml information
     * @param key the configuration key node
     * @return the hierarchical configurations, empty if exception happens
     */
    public static List<HierarchicalConfiguration> configsAt(String content, String key) {
        List<HierarchicalConfiguration> info;
        try {
            HierarchicalConfiguration cfg = XmlConfigParser.loadXmlString(content);
            info = cfg.configurationsAt(key);
        } catch (Exception e) {
            // Accept empty for information polling
            return ImmutableList.of();
        }
        return info;
    }

    /**
     * Makes a xml format sentence.
     *
     * @param node the node name
     * @param content the node content
     * @return the xml format sentence
     */
    public static String xml(String node, String content) {
        return String.format("<%s>%s</%s>", node, content, node);
    }

    /**
     * Makes a xml format open tag.
     *
     * @param node the node name
     * @return the xml head format string
     */
    public static String xmlOpen(String node) {
        return String.format("<%s>", node);
    }

    /**
     * Makes a xml format close tag.
     *
     * @param node the node name
     * @return the xml end format string
     */
    public static String xmlClose(String node) {
        return String.format("</%s>", node);
    }

    /**
     * Makes a xml format empty tag.
     *
     * @param node the node name
     * @return the xml format of empty tag
     */
    public static String xmlEmpty(String node) {
        return String.format("<%s/>", node);
    }
}
