#!/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, port_ssh):
        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
        self.port_ssh = port_ssh

    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,
                port=self.port_ssh,
                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
            print("SSH Login: Exception: %s" % e)

        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
