#!/usr/bin/env python3

import os
import sys

from robot.libraries.BuiltIn import BuiltIn as robotBuildIn

sys.path.append(__file__.split(__file__.split("/")[-1])[0] + "../ffdc")
from ffdc_collector import ffdc_collector  # NOQA
from ssh_utility import SSHRemoteclient  # NOQA

# (Sub) String constants used for input dictionary key search
HOST = "HOST"
USER = "USERNAME"
PASSWD = "PASSWORD"
PORT_SSH = "SSH_PORT"
PORT_HTTPS = "HTTPS_PORT"
PORT_IPMI = "IPMI_PORT"
CONFIG = "CONFIG"
TYPE = "TYPE"
LOC = "LOCATION"
PROTOCOL = "PROTOCOL"
ENV_VARS = "ENV_VARS"
ECONFIG = "ECONFIG"
LOGLEVEL = "LOG"


def ffdc_robot_script_cli(**kwargs):
    r"""

    For the specified host, this method provide automation testcases the interface to
    the new ffdc collector ../ffdc/ffdc_collector.py via robot variable FFDC_DEFAULT

    variable FFDC_DEFAULT:1, by default use the existing ffdc collection method.
    variable FFDC_DEFAULT:0 use the new ffdc method

    Command examples:
    (1) Legacy ffdc collection
    python3 -m robot -v OPENBMC_HOST:<> -v OPENBMC_USERNAME:<> \
                                        -v OPENBMC_PASSWORD:<> ./tools/myffdc.robot
    (2) New ffdc collection
    python3 -m robot -v OPENBMC_HOST:<> -v OPENBMC_USERNAME:<> \
                        -v OPENBMC_PASSWORD:<> -v FFDC_DEFAULT:0  ./tools/myffdc.robot

    Description of argument(s)in dictionary: xx can be anything appropriate

        xx_HOST:hostname                name/ip of the targeted (remote) system
        xx_USERNAME:username            user on the targeted system with access to FFDC files
        xx_PASSWORD:password            password for user on targeted system
        xx_CONFIG:ffdc_config           configuration file listing commands and files for FFDC
        xx_LOCATION:location            where to store collected FFDC.  Default: <current dir>/logs/
        xx_TYPE:remote_type             os type of the remote host.
        xx_PROTOCOL:remote_protocol     Protocol to use to collect data. Default: 'ALL'
        ENV_VAR:env_vars                User define CLI env vars '{"key : "value"}'. Default: ""
        ECONFIG:econfig                 User define env vars YAML file. Default: ""
        LOG_LEVEL:log_level             CRITICAL, ERROR, WARNING, INFO, DEBUG. Default: INFO

    Code examples:
    (1) openbmc_ffdc.robot activate this method with no parm
        Run Keyword If  ${FFDC_DEFAULT} == ${1}  FFDC
    ...    ELSE  ffdc_robot_script_cli

    (2) Method invocation with parms
        ffdc_from = {'OS_HOST' : 'os host name or ip',
                     'OS_USERNAME' : 'os username',
                     'OS_PASSWORD' : 'password for os_username',
                     'OS_TYPE'     : 'os_type, ubuntu, rhel, aix, etc',
                    }
        ffdc_robot_script_cli(ffdc_from)

    """

    robotBuildIn().log_to_console("Collecting FFDC - CLI log collector script")

    if not kwargs:
        dict_of_parms = {}
        # When method is invoked with no parm,
        # use robot variables
        # OPENBMC_HOST, OPENBMC_USERNAME, OPENBMC_PASSWORD, OPENBMC (type)
        dict_of_parms["OPENBMC_HOST"] = robotBuildIn().get_variable_value(
            "${OPENBMC_HOST}", default=None
        )
        dict_of_parms["OPENBMC_USERNAME"] = robotBuildIn().get_variable_value(
            "${OPENBMC_USERNAME}", default=None
        )
        dict_of_parms["OPENBMC_PASSWORD"] = robotBuildIn().get_variable_value(
            "${OPENBMC_PASSWORD}", default=None
        )
        dict_of_parms["SSH_PORT"] = robotBuildIn().get_variable_value(
            "${SSH_PORT}", default=22
        )
        dict_of_parms["HTTPS_PORT"] = robotBuildIn().get_variable_value(
            "${HTTPS_PORT}", default=443
        )
        dict_of_parms["IPMI_PORT"] = robotBuildIn().get_variable_value(
            "${IPMI_PORT}", default=623
        )
        dict_of_parms["REMOTE_TYPE"] = "OPENBMC"

        run_ffdc_collector(dict_of_parms)

    else:
        if isinstance(kwargs, dict):
            # When method is invoked with user defined dictionary,
            # dictionary keys has the following format
            # xx_HOST; xx_USERNAME, xx_PASSWORD, xx_TYPE
            # where xx is one of OPENBMC, OS, or os_type LINUX/UBUNTU/AIX
            run_ffdc_collector(**kwargs)


def run_ffdc_collector(dict_of_parm):
    r"""

    Process input parameters and collect information

    Description of argument(s)in dictionary: xx can be anything appropriate

        xx_HOST:hostname                name/ip of the targeted (remote) system
        xx_USERNAME:username            user on the targeted system with access to FFDC files
        xx_PASSWORD:password            password for user on targeted system
        xx_CONFIG:ffdc_config           configuration file listing commands and files for FFDC
        xx_LOCATION:location            where to store collected FFDC.  Default: <current dir>/logs/
        xx_TYPE:remote_type             os type of the remote host.
        xx_PROTOCOL:remote_protocol     Protocol to use to collect data. Default: 'ALL'
        ENV_VAR:env_vars                User define CLI env vars '{"key : "value"}'. Default: ""
        ECONFIG:econfig                 User define env vars YAML file. Default: ""
        LOG_LEVEL:log_level             CRITICAL, ERROR, WARNING, INFO, DEBUG. Default: INFO

    """

    # Clear local variables
    remote = None
    username = None
    password = None
    config = None
    location = None
    remote_type = None
    protocol = None
    env_vars = None
    econfig = None
    log_level = None

    # Process input key/value pairs
    for key in dict_of_parm.keys():
        if HOST in key:
            remote = dict_of_parm[key]
        elif USER in key:
            username = dict_of_parm[key]
        elif PASSWD in key:
            password = dict_of_parm[key]
        elif PORT_SSH in key:
            port_ssh = dict_of_parm[key]
        elif PORT_HTTPS in key:
            port_https = dict_of_parm[key]
        elif PORT_IPMI in key:
            port_ipmi = dict_of_parm[key]
        elif CONFIG in key:
            config = dict_of_parm[key]
        elif LOC in key:
            location = dict_of_parm[key]
        elif TYPE in key:
            remote_type = dict_of_parm[key]
        elif PROTOCOL in key:
            protocol = dict_of_parm[key]
        elif ENV_VARS in key:
            env_vars = dict_of_parm[key]
        elif ECONFIG in key:
            econfig = dict_of_parm[key]
        elif LOGLEVEL in key:
            log_level = dict_of_parm[key]

    # Set defaults values for parms
    # that are not specified with input and have acceptable defaults.
    if not location:
        # Default FFDC store location
        location = (
            robotBuildIn().get_variable_value("${EXECDIR}", default=None)
            + "/logs"
        )
        ffdc_collector.validate_local_store(location)

    if not config:
        # Default FFDC configuration
        script_path = os.path.dirname(os.path.abspath(__file__))
        config = script_path + "/../ffdc/ffdc_config.yaml"

    if not protocol:
        protocol = "ALL"

    if not env_vars:
        env_vars = ""

    if not econfig:
        econfig = ""

    if not log_level:
        log_level = "INFO"

    # If minimum required inputs are met, go collect.
    if remote and username and password and remote_type:
        # Execute data collection
        this_ffdc = ffdc_collector(
            remote,
            username,
            password,
            port_ssh,
            port_https,
            port_ipmi,
            config,
            location,
            remote_type,
            protocol,
            env_vars,
            econfig,
            log_level,
        )
        this_ffdc.collect_ffdc()

        # If original ffdc request is for BMC,
        #  attempt to also collect ffdc for HOST_OS if possible.
        if remote_type.upper() == "OPENBMC":
            os_host = robotBuildIn().get_variable_value(
                "${OS_HOST}", default=None
            )
            os_username = robotBuildIn().get_variable_value(
                "${OS_USERNAME}", default=None
            )
            os_password = robotBuildIn().get_variable_value(
                "${OS_PASSWORD}", default=None
            )

            if os_host and os_username and os_password:
                os_type = get_os_type(os_host, os_username, os_password)
                if os_type:
                    os_ffdc = ffdc_collector(
                        os_host,
                        os_username,
                        os_password,
                        config,
                        location,
                        os_type,
                        protocol,
                        env_vars,
                        econfig,
                        log_level,
                    )
                    os_ffdc.collect_ffdc()


def get_os_type(os_host, os_username, os_password):
    os_type = None

    # If HOST_OS is pingable
    if os.system("ping -c 1 " + os_host) == 0:
        r"""
        Open a ssh connection to targeted system.
        """
        ssh_remoteclient = SSHRemoteclient(os_host, os_username, os_password)

        if ssh_remoteclient.ssh_remoteclient_login():
            # Find OS_TYPE
            cmd_exit_code, err, response = ssh_remoteclient.execute_command(
                "uname"
            )
            os_type = response.strip()

            # If HOST_OS is linux, expands os_type to one of
            # the 2 linux distros that have more details in ffdc_config.yaml
            if os_type.upper() == "LINUX":
                (
                    cmd_exit_code,
                    err,
                    response,
                ) = ssh_remoteclient.execute_command("cat /etc/os-release")
                linux_distro = response
                if "redhat" in linux_distro:
                    os_type = "RHEL"
                elif "ubuntu" in linux_distro:
                    os_type = "UBUNTU"

        if ssh_remoteclient:
            ssh_remoteclient.ssh_remoteclient_disconnect()

    return os_type
