#!/usr/bin/env python3

import logging
import socket
import time
from socket import timeout as SocketTimeout

import paramiko
from paramiko.buffered_pipe import PipeTimeout as PipeTimeout
from paramiko.ssh_exception import (
    AuthenticationException,
    BadHostKeyException,
    NoValidConnectionsError,
    SSHException,
)
from scp import SCPClient, SCPException


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,
                banner_timeout=120,
                timeout=60,
                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:
                # Need to do read/write operation to trigger
                # paramiko exec_command timeout mechanism.
                xresults = stderr.readlines()
                results = "".join(xresults)
                time.sleep(1)
                if stdout.channel.exit_status_ready():
                    break
            cmd_exit_code = stdout.channel.recv_exit_status()

            # Convert list of string to one string
            err = ""
            out = ""
            for item in results:
                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, SSHException) 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)
            )
            # Pause for 2 seconds allowing Paramiko to finish error processing before next fetch.
            # Without the delay after SCPException,
            #    next fetch will get 'paramiko.ssh_exception.SSHException'> Channel closed Error.
            time.sleep(2)
            return False
        # Return True for file accounting
        return True
