/*
 * Copyright 2015 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.provider.netconf.device.impl;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.delay;
import static org.slf4j.LoggerFactory.getLogger;

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

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import org.slf4j.Logger;

import com.tailf.jnc.Capabilities;
import com.tailf.jnc.JNCException;
import com.tailf.jnc.SSHConnection;
import com.tailf.jnc.SSHSession;

/**
 * This is a logical representation of actual NETCONF device, carrying all the
 * necessary information to connect and execute NETCONF operations.
 */
public class NetconfDevice {
    private final Logger log = getLogger(NetconfDevice.class);

    /**
     * The Device State is used to determine whether the device is active or
     * inactive. This state infomation will help Device Creator to add or delete
     * the device from the core.
     */
    public static enum DeviceState {
        /* Used to specify Active state of the device */
        ACTIVE,
        /* Used to specify inactive state of the device */
        INACTIVE,
        /* Used to specify invalid state of the device */
        INVALID
    }

    private static final int DEFAULT_SSH_PORT = 22;
    private static final int DEFAULT_CON_TIMEOUT = 0;
    private static final String XML_CAPABILITY_KEY = "capability";
    private static final int EVENTINTERVAL = 2000;
    private static final int CONNECTION_CHECK_INTERVAL = 3;
    private static final String INPUT_HELLO_XML_MSG = new StringBuilder(
                                                                        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
            .append("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">")
            .append("<capabilities><capability>urn:ietf:params:netconf:base:1.0</capability>")
            .append("</capabilities></hello>").toString();

    private String sshHost;
    private int sshPort = DEFAULT_SSH_PORT;
    private int connectTimeout = DEFAULT_CON_TIMEOUT;
    private String username;
    private String password;
    private boolean reachable = false;

    private List<String> capabilities = new ArrayList<String>();
    private SSHConnection sshConnection = null;

    private DeviceState deviceState = DeviceState.INVALID;

    protected NetconfDevice(String sshHost, int sshPort, String username,
                            String password) {
        this.username = checkNotNull(username,
                                     "Netconf Username Cannot be null");
        this.sshHost = checkNotNull(sshHost, "Netconf Device IP cannot be null");
        this.sshPort = checkNotNull(sshPort,
                                    "Netconf Device SSH port cannot be null");
        this.password = password;
    }

    /**
     * This will try to connect to NETCONF device and find all the capabilities.
     *
     * @throws Exception if unable to connect to the device
     */
    // FIXME: this should not be a generic Exception; perhaps wrap in some RuntimeException
    public void init() throws Exception {
        try {
            if (sshConnection == null) {
                sshConnection = new SSHConnection(sshHost, sshPort, connectTimeout);
                sshConnection.authenticateWithPassword(username, password);
            }
            // Send hello message to retrieve capabilities.
        } catch (IOException e) {
            log.error("Fatal Error while creating connection to the device: "
                    + deviceInfo(), e);
            throw e;
        } catch (JNCException e) {
            log.error("Failed to connect to the device: " + deviceInfo(), e);
            throw e;
        }

        hello();
    }

    private void hello() {
        SSHSession ssh = null;
        try {
            ssh = new SSHSession(sshConnection);
            String helloRequestXML = INPUT_HELLO_XML_MSG.trim();

            log.debug("++++++++++++++++++++++++++++++++++Sending Hello: "
                    + sshConnection.getGanymedConnection().getHostname()
                    + "++++++++++++++++++++++++++++++++++");
            printPrettyXML(helloRequestXML);
            ssh.print(helloRequestXML);
            // ssh.print(endCharSeq);
            ssh.flush();
            String xmlResponse = null;
            int i = CONNECTION_CHECK_INTERVAL;
            while (!ssh.ready() && i > 0) {
                delay(EVENTINTERVAL);
                i--;
            }

            if (ssh.ready()) {
                StringBuffer readOne = ssh.readOne();
                if (readOne == null) {
                    log.error("The Hello Contains No Capabilites");
                    throw new JNCException(
                                           JNCException.SESSION_ERROR,
                                           "server does not support NETCONF base capability: "
                                                   + Capabilities.NETCONF_BASE_CAPABILITY);
                } else {
                    xmlResponse = readOne.toString().trim();

                    log.debug("++++++++++++++++++++++++++++++++++Reading Capabilities: "
                            + sshConnection.getGanymedConnection()
                                    .getHostname()
                            + "++++++++++++++++++++++++++++++++++");

                    printPrettyXML(xmlResponse);
                    processCapabilities(xmlResponse);
                }
            }
            reachable = true;
        } catch (IOException e) {
            log.error("Fatal Error while sending Hello Message to the device: "
                    + deviceInfo(), e);
        } catch (JNCException e) {
            log.error("Fatal Error while sending Hello Message to the device: "
                    + deviceInfo(), e);
        } finally {
            log.debug("Closing the session after successful execution");
            ssh.close();
        }
    }

    private void processCapabilities(String xmlResponse) throws JNCException {
        if (xmlResponse.isEmpty()) {
            log.error("The capability response cannot be empty");
            throw new JNCException(
                                   JNCException.SESSION_ERROR,
                                   "server does not support NETCONF base capability: "
                                           + Capabilities.NETCONF_BASE_CAPABILITY);
        }
        try {
            Document doc = new SAXBuilder()
                    .build(new StringReader(xmlResponse));
            Element rootElement = doc.getRootElement();
            processCapabilities(rootElement);
        } catch (Exception e) {
            log.error("ERROR while parsing the XML " + xmlResponse);
        }
    }

    private void processCapabilities(Element rootElement) {
        List<Element> children = rootElement.getChildren();
        if (children.isEmpty()) {
            return;
        }
        for (Element child : children) {

            if (child.getName().equals(XML_CAPABILITY_KEY)) {
                capabilities.add(child.getValue());
            }
            if (!child.getChildren().isEmpty()) {
                processCapabilities(child);
            }
        }
    }

    private void printPrettyXML(String xmlstring) {
        try {
            Document doc = new SAXBuilder().build(new StringReader(xmlstring));
            XMLOutputter xmOut = new XMLOutputter(Format.getPrettyFormat());
            String outputString = xmOut.outputString(doc);
            log.debug(outputString);
        } catch (Exception e) {
            log.error("ERROR while parsing the XML " + xmlstring, e);

        }
    }

    /**
     * This would return host IP and host Port, used by this particular Netconf
     * Device.
     * @return Device Information.
     */
    public String deviceInfo() {
        return new StringBuilder("host: ").append(sshHost).append(". port: ")
                .append(sshPort).toString();
    }

    /**
     * This will terminate the device connection.
     */
    public void disconnect() {
        sshConnection.close();
        reachable = false;
    }

    /**
     * This will list down all the capabilities supported on the device.
     * @return Capability list.
     */
    public List<String> getCapabilities() {
        return capabilities;
    }

    /**
     * This api is intended to know whether the device is connected or not.
     * @return true if connected
     */
    public boolean isReachable() {
        return reachable;
    }

    /**
     * This will return the IP used connect ssh on the device.
     * @return Netconf Device IP
     */
    public String getSshHost() {
        return sshHost;
    }

    /**
     * This will return the SSH Port used connect the device.
     * @return SSH Port number
     */
    public int getSshPort() {
        return sshPort;
    }

    /**
     * The usename used to connect Netconf Device.
     * @return Device Username
     */
    public String getUsername() {
        return username;
    }

    /**
     * Retrieve current state of the device.
     * @return Current Device State
     */
    public DeviceState getDeviceState() {
        return deviceState;
    }

    /**
     * This is set the state information for the device.
     * @param deviceState Next Device State
     */
    public void setDeviceState(DeviceState deviceState) {
        this.deviceState = deviceState;
    }

    /**
     * Check whether the device is in Active state.
     * @return true if the device is Active
     */
    public boolean isActive() {
        return deviceState == DeviceState.ACTIVE ? true : false;
    }

    public void setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
    }
}
