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