/*
 * 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 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 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.
     */
    public void init() throws Exception {
        try {
            if (sshConnection == null) {
                sshConnection = new SSHConnection(sshHost, sshPort);
                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;
    }
}
