#!/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
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)

            return stderr.readlines(), stdout.readlines()

        except (paramiko.AuthenticationException, paramiko.SSHException,
                paramiko.ChannelException, SocketTimeout) as e:
            # Log command with error. Return to caller for next command, if any.
            print("\n>>>>>\tERROR: Fail remote command %s %s" % (e.__class__, e))
            print(">>>>>\tCommand '%s' Elapsed Time %s" %
                  (command, time.strftime("%H:%M:%S", time.gmtime(time.time() - cmd_start))))
            return 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)
            print("\n\t[Check] %s SCP transport established.\t [OK]" % self.hostname)
        except (SCPException, SocketTimeout, PipeTimeout) as e:
            self.scpclient = None
            print("\n>>>>>\tERROR: SCP get_transport has failed. %s %s" % (e.__class__, e))
            print(">>>>>\tScript continues generating FFDC on %s." % self.hostname)
            print(">>>>>\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.
            print("\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
