/*
 * Copyright 2018-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.drivers.netconf;

import static org.slf4j.LoggerFactory.getLogger;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.io.IOUtils;
import org.onosproject.netconf.NetconfException;
import org.onosproject.netconf.NetconfSession;
import org.slf4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import com.google.common.io.Resources;

/**
 * Manages templates and provides utilities to execute these templates against a
 * NETCONF session.
 */
public final class TemplateManager {
    private static final Logger log = getLogger(TemplateManager.class);
    private final Map<String, String> templates = new HashMap<String, String>();
    private TemplateRequestDriver requestDriver;
    public static final Map<String, Object> EMPTY_TEMPLATE_CONTEXT = new HashMap<String, Object>();

    /**
     * Internal implementation of the request driver that implements a NETCONF
     * driver.
     */
    private class InternalRequestDriver implements TemplateRequestDriver {
        @Override
        public Object doRequest(NetconfSession session, String templateName, Map<String, Object> templateContext,
                String baseXPath, QName returnType) throws NetconfException {
            try {
                String data = session.rpc(render(templates.get(templateName), templateContext)).get();
                InputStream resp = IOUtils.toInputStream(data, StandardCharsets.UTF_8);
                DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = builderFactory.newDocumentBuilder();
                Document document = builder.parse(resp);
                XPath xp = XPathFactory.newInstance().newXPath();
                return xp.evaluate(baseXPath, document, returnType);
            } catch (Exception e) {
                NetconfException ne = new NetconfException(e.getMessage(), e);
                throw ne;
            }
        }
    }

    /**
     * Constructs a new template manager and loads the default templates.
     */
    public TemplateManager() {
        requestDriver = new InternalRequestDriver();
    }

    /**
     * Sets the request driver for the template manager.
     *
     * @param driver
     *            the driver to use
     */
    public void setRequestDriver(TemplateRequestDriver driver) {
        requestDriver = driver;
    }

    /**
     * Loads the named templates into the template manager.
     *
     * @param reference
     *            the class reference from which to load resources
     * @param pattern
     *            pattern to convert template name to resource path
     * @param templateNames
     *            list of template to load
     */
    public void load(Class<? extends Object> reference, String pattern, String... templateNames) {
        for (String name : templateNames) {
            String key = name;
            String resource;

            // If the template name begins with a '/', then assume it is a full path
            // specification
            if (name.charAt(0) == '/') {
                int start = name.lastIndexOf('/') + 1;
                int end = name.lastIndexOf('.');
                if (end == -1) {
                    key = name.substring(start);
                } else {
                    key = name.substring(start, end);
                }
                resource = name;
            } else {
                resource = String.format(pattern, name);
            }

            log.error("LOAD TEMPLATE: '{}' as '{}' from '{}", name, key, resource);

            try {
                templates.put(name,
                        Resources.toString(Resources.getResource(reference, resource), StandardCharsets.UTF_8));

            } catch (IOException ioe) {
                log.error("Unable to load NETCONF request template '{}' from '{}'", key, resource, ioe);
            }
        }
    }

    /**
     * Loads the named templates into the template manager using the default
     * reference class and resource path pattern.
     *
     * @param templateMNames
     *            list of template to load
     */
    public void load(String... templateMNames) {
        load(this.getClass(), "/templates/requests/%s.j2", templateMNames);
    }

    /**
     * Loads the named templates into the template manager using the default
     * reference class.
     *
     * @param pattern
     *            pattern to convert template name to resource path
     * @param templateMNames
     *            list of template to load
     */
    public void load(String pattern, String... templateMNames) {
        load(this.getClass(), pattern, templateMNames);
    }

    /**
     * Returns the named template.
     *
     * @param templateName
     *            name of template to return
     * @return template
     */
    public String get(String templateName) {
        return templates.get(templateName);
    }

    /**
     * Performs simple variable substitution into a string in likely the most
     * inefficient way possible.
     *
     * @param template
     *            template into which to substitute variables
     * @param context
     *            variable substitution map
     * @return template rendered with variable substitution
     */
    public String render(String template, Map<String, Object> context) {
        if (context == null) {
            return template;
        }

        String temp = template;
        for (Map.Entry<String, Object> e : context.entrySet()) {
            temp = temp.replaceAll("\\{\\{ *" + e.getKey() + " *\\}\\}", e.getValue().toString());
        }
        return temp;
    }

    /**
     * Executes the named NETCONF template against the specified session, returning
     * the referenced XML node as the specified type.
     *
     * @param session
     *            NETCONF serssion
     * @param templateName
     *            name of NETCONF request template to execute
     * @param templateContext
     *            variable to values substitutions to be used against templates
     * @param baseXPath
     *            XPath expression to specify the returned document node
     * @param returnType
     *            expected return type of the referenced node
     * @return XML document node referenced by the {@code baseXPath}
     * @throws NetconfException
     *             if any IO, XPath, or NETCONF exception occurs
     */
    public Object doRequest(NetconfSession session, String templateName, Map<String, Object> templateContext,
            String baseXPath, QName returnType) throws NetconfException {
        return requestDriver.doRequest(session, templateName, templateContext, baseXPath, returnType);
    }

    /**
     * Execute the named NETCONF template against the specified session returning
     * the {@code /rpc-reply/data} section of the response document as a
     * {@code Node}.
     *
     * @param session
     *            NETCONF session
     * @param templateName
     *            name of NETCONF request template to execute
     * @return XML document node that represents the NETCONF response data
     * @throws NetconfException
     *             if any IO, XPath, or NETCONF exception occurs
     */
    public Node doRequest(NetconfSession session, String templateName) throws NetconfException {
        return (Node) doRequest(session, templateName, EMPTY_TEMPLATE_CONTEXT, "/rpc-reply/data", XPathConstants.NODE);
    }

    /**
     * Execute the named NETCONF template with the given template context against
     * the specified session returning the {@code /rpc-reply/data} section of the
     * response document as a {@code Node}.
     *
     * @param session
     *            NETCONF session
     * @param templateName
     *            name of NETCONF request template to execute
     * @param templateContext
     *            variables to substitute into the template
     * @return XML document node that represents the NETCONF response data
     * @throws NetconfException
     *             if any IO, XPath, or NETCONF exception occurs
     */
    public Node doRequest(NetconfSession session, String templateName, Map<String, Object> templateContext)
            throws NetconfException {
        return (Node) doRequest(session, templateName, templateContext, "/rpc-reply/data", XPathConstants.NODE);
    }
}
