/*
 * 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 org.apache.commons.configuration.HierarchicalConfiguration;
import org.onosproject.drivers.utilities.XmlConfigParser;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.netconf.NetconfController;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;

import java.io.IOException;

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_TAR_RUNNING = "running";
    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 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(CFG_TAR_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(CFG_TAR_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
     */
    public static HierarchicalConfiguration configAt(String content, String key) {
        HierarchicalConfiguration cfg = XmlConfigParser.loadXmlString(content);
        HierarchicalConfiguration info;
        try {
            info = cfg.configurationAt(key);
        } catch (Exception e) {
            // Accept null for information polling
            return null;
        }
        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);
    }
}
