#!/usr/bin/env python

import paramiko
from paramiko.ssh_exception import AuthenticationException
from paramiko.ssh_exception import NoValidConnectionsError
from paramiko.ssh_exception import SSHException
from paramiko.ssh_exception import BadHostKeyException
from paramiko.buffered_pipe import PipeTimeout as PipeTimeout
from scp import SCPClient, SCPException
import time
import socket
import logging
from socket import timeout as SocketTimeout


class SSHRemoteclient:
    r"""
    Class to create ssh connection to remote host
    for remote host command execution and scp.
    """

    def __init__(self, hostname, username, password):

        r"""
        Description of argument(s):

        hostname        Name/IP of the remote (targeting) host
        username        User on the remote host with access to FFCD files
        password        Password for user on remote host
        """

        self.ssh_output = None
        self.ssh_error = None
        self.sshclient = None
        self.scpclient = None
        self.hostname = hostname
        self.username = username
        self.password = password

    def ssh_remoteclient_login(self):

        r"""
        Method to create a ssh connection to remote host.
        """

        is_ssh_login = True
        try:
            # SSHClient to make connections to the remote server
            self.sshclient = paramiko.SSHClient()
            # setting set_missing_host_key_policy() to allow any host
            self.sshclient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            # Connect to the server
            self.sshclient.connect(hostname=self.hostname,
                                   username=self.username,
                                   password=self.password,
                                   look_for_keys=False)

        except (BadHostKeyException, AuthenticationException,
                SSHException, NoValidConnectionsError, socket.error) as e:
            is_ssh_login = False

        return is_ssh_login

    def ssh_remoteclient_disconnect(self):

        r"""
        Clean up.
        """

        if self.sshclient:
            self.sshclient.close()

        if self.scpclient:
            self.scpclient.close()

    def execute_command(self, command,
                        default_timeout=60):
        """
        Execute command on the remote host.

        Description of argument(s):
        command                Command string sent to remote host

        """

        empty = ''
        cmd_start = time.time()
        try:
            stdin, stdout, stderr = \
                self.sshclient.exec_command(command, timeout=default_timeout)
            start = time.time()
            while time.time() < start + default_timeout:
                if stdout.channel.exit_status_ready():
                    break
                time.sleep(1)
            cmd_exit_code = stdout.channel.recv_exit_status()

            # Convert list of string to one string
            err = ''
            out = ''
            for item in stderr.readlines():
                err += item
            for item in stdout.readlines():
                out += item

            return cmd_exit_code, err, out

        except (paramiko.AuthenticationException, paramiko.SSHException,
                paramiko.ChannelException, SocketTimeout) as e:
            # Log command with error. Return to caller for next command, if any.
            logging.error("\n\tERROR: Fail remote command %s %s" % (e.__class__, e))
            logging.error("\tCommand '%s' Elapsed Time %s" %
                          (command, time.strftime("%H:%M:%S", time.gmtime(time.time() - cmd_start))))
            return 0, empty, empty

    def scp_connection(self):

        r"""
        Create a scp connection for file transfer.
        """
        try:
            self.scpclient = SCPClient(self.sshclient.get_transport(), sanitize=lambda x: x)
            logging.info("\n\t[Check] %s SCP transport established.\t [OK]" % self.hostname)
        except (SCPException, SocketTimeout, PipeTimeout) as e:
            self.scpclient = None
            logging.error("\n\tERROR: SCP get_transport has failed. %s %s" % (e.__class__, e))
            logging.info("\tScript continues generating FFDC on %s." % self.hostname)
            logging.info("\tCollected data will need to be manually offloaded.")

    def scp_file_from_remote(self, remote_file, local_file):

        r"""
        scp file in remote system to local with date-prefixed filename.

        Description of argument(s):
        remote_file            Full path filename on the remote host

        local_file             Full path filename on the local host
                               local filename = date-time_remote filename

        """

        try:
            self.scpclient.get(remote_file, local_file, recursive=True)
        except (SCPException, SocketTimeout, PipeTimeout) as e:
            # Log command with error. Return to caller for next file, if any.
            logging.error(
                "\n\tERROR: Fail scp %s from remotehost %s %s\n\n" % (remote_file, e.__class__, e))
            return False

        # Return True for file accounting
        return True
