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

        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
