#!/usr/bin/env python3

r"""
This module provides many valuable openbmctool.py functions such as
openbmctool_execute_command.
"""

import collections
import json
import re
import tempfile

import gen_cmd as gc
import gen_misc as gm
import gen_print as gp
import gen_valid as gv
import utils as utils
import var_funcs as vf
from robot.libraries.BuiltIn import BuiltIn


def openbmctool_execute_command(command_string, *args, **kwargs):
    r"""
    Run the command string as an argument to the openbmctool.py program and
    return the stdout and the return code.

    This function provides several benefits versus calling shell_cmd directly:
    - This function will obtain the global values for OPENBMC_HOST,
      OPENBMC_USERNAME, etc.
    - This function will compose the openbmctool.py command string which
      includes the caller's command_string.
    - The openbmctool.py produces additional text that clutters the output.
      This function will remove such text.  Example:
        Attempting login...
        <actual output>
        User root has been logged out

    NOTE: If you have pipe symbols in your command_string, they must be
    surrounded by a single space on each side (see example below).

    Example code:
    ${rc}  ${output}=  Openbmctool Execute Command  fru status | head -n 2

    Example output:
    #(CDT) 2018/09/19 15:16:58 - Issuing: set -o pipefail ; openbmctool.py -H hostname -U root -P ********
    ...  fru status | tail -n +1 | egrep -v 'Attempting login|User [^ ]+ hasbeen logged out' | head -n 2
    Component     | Is a FRU  | Present  | Functional  | Has Logs
    cpu0          | Yes       | Yes      | Yes         | No

    Description of arguments:
    command_string                  The command string to be passed to the
                                    openbmctool.py program.
    All remaining arguments are passed directly to shell_cmd.  See the
    shell_cmd prolog for details on allowable arguments.  The caller may code
    them directly as in this example:
    openbmctool_execute_command("my command", quiet=1, max_attempts=2).
    Python will do the work of putting these values into args/kwargs.
    """

    if not gv.valid_value(command_string):
        return "", "", 1

    # Get global BMC variable values.
    openbmc_host = BuiltIn().get_variable_value("${OPENBMC_HOST}", default="")
    https_port = BuiltIn().get_variable_value("${HTTPS_PORT}", default="443")
    openbmc_username = BuiltIn().get_variable_value(
        "${OPENBMC_USERNAME}", default=""
    )
    openbmc_password = BuiltIn().get_variable_value(
        "${OPENBMC_PASSWORD}", default=""
    )
    if not gv.valid_value(openbmc_host):
        return "", "", 1
    if not gv.valid_value(openbmc_username):
        return "", "", 1
    if not gv.valid_value(openbmc_password):
        return "", "", 1
    if not gv.valid_value(https_port):
        return "", "", 1

    # Break the caller's command up into separate piped commands.  For
    # example, the user may have specified "fru status | head -n 2" which
    # would be broken into 2 list elements.  We will also break on ">"
    # (re-direct).
    pipeline = list(
        map(str.strip, re.split(r" ([\|>]) ", str(command_string)))
    )
    # The "tail" command below prevents a "egrep: write error: Broken pipe"
    # error if the user is piping the output to a sub-process.
    # Use "egrep -v" to get rid of editorial output from openbmctool.py.
    pipeline.insert(
        1,
        (
            "| tail -n +1 | egrep -v 'Attempting login|User [^ ]+"
            " has been logged out'"
        ),
    )

    command_string = (
        "set -o pipefail ; python3 $(which openbmctool.py) -H "
        + openbmc_host
        + ":"
        + https_port
        + " -U "
        + openbmc_username
        + " -P "
        + openbmc_password
        + " "
        + " ".join(pipeline)
    )

    return gc.shell_cmd(command_string, *args, **kwargs)


def openbmctool_execute_command_json(command_string, *args, **kwargs):
    r"""
    Run the command string as an argument to the openbmctool.py program, parse
    the JSON output into a dictionary and return the dictionary.

    This function is a wrapper for openbmctool_execute_command (defined
    above).  The caller may provide any command string where the output will
    be JSON data.  This function will convert the JSON data to a python
    object, verify that the 'status' field = "ok" and return the 'data'
    sub-field to the caller.

    See openbmctool_execute_command (above) for all field descriptions.
    """

    rc, output = openbmctool_execute_command(command_string, *args, **kwargs)
    try:
        json_object = utils.to_json_ordered(output)
    except json.JSONDecodeError:
        BuiltIn().fail(gp.sprint_error(output))

    if json_object["status"] != "ok":
        err_msg = "Error found in JSON data returned by the openbmctool.py "
        err_msg += "command. Expected a 'status' field value of \"ok\":\n"
        err_msg += gp.sprint_var(json_object, 1)
        BuiltIn().fail(gp.sprint_error(err_msg))

    return json_object["data"]


def get_fru_status():
    r"""
    Get the fru status and return as a list of dictionaries.

    Example robot code:

    ${fru_status}=  Get Fru Status
    Rprint Vars  fru_status  fmt=1

    Example result (excerpt):

    fru_status:
      fru_status[0]:
        [component]:             cpu0
        [is_a]:                  Yes
        [fru]:                   Yes
        [present]:               Yes
        [functional]:            No
      fru_status[1]:
        [component]:             cpu0-core0
        [is_a]:                  No
        [fru]:                   Yes
        [present]:               Yes
        [functional]:            No
    ...
    """
    rc, output = openbmctool_execute_command(
        "fru status", print_output=False, ignore_err=False
    )
    # Example value for output (partial):
    # Component     | Is a FRU  | Present  | Functional  | Has Logs
    # cpu0          | Yes       | Yes      | Yes         | No
    # cpu0-core0    | No        | Yes      | Yes         | No
    # ...

    # Replace spaces with underscores in field names (e.g. "Is a FRU" becomes
    # "Is_a_FRU").
    output = re.sub("([^ \\|])[ ]([^ ])", "\\1_\\2", output)
    output = re.sub("([^ \\|])[ ]([^ ])", "\\1_\\2", output)

    return vf.outbuf_to_report(output, field_delim="|")


def get_fru_print(parse_json=True):
    r"""
    Get the output of the fru print command and return it either as raw JSON
    data or as a list of dictionaries.

    Example robot code:

    ${fru_print}=  Get Fru Print  parse_json=${False}
    Log to Console  ${fru_print}

    Example result (excerpt):

    {
      "data": {
        "/xyz/openbmc_project/inventory/system": {
          "AssetTag": "",
          "BuildDate": "",
          "Cached": false,
          "FieldReplaceable": false,
          "Manufacturer": "",
          "Model": "xxxxxxxx",
          "PartNumber": "",
          "Present": true,
          "PrettyName": "",
          "SerialNumber": "13183FA"
        },
        "/xyz/openbmc_project/inventory/system/chassis": {
          "AirCooled": true,
          "WaterCooled": false
        },
    ...

    Example robot code:

    ${fru_print}=  Get Fru Print
    Rprint Vars  fru_print  fmt=1

    Example result (excerpt):

    fru_print:
      fru_print[0]:
        [data]:
          [/xyz/openbmc_project/inventory/system]:
            [AssetTag]:          <blank>
            [BuildDate]:         <blank>
            [Cached]:            False
            [FieldReplaceable]:  False
            [Manufacturer]:      <blank>
            [Model]:             xxxxxxxx
            [PartNumber]:        <blank>
            [Present]:           True
            [PrettyName]:        <blank>
            [SerialNumber]:      13183FA
          [/xyz/openbmc_project/inventory/system/chassis]:
            [AirCooled]:         True
            [WaterCooled]:       False
    ...

    Description of argument(s):
    parse_json                      Indicates that the raw JSON data should
                                    parsed into a list of dictionaries.
    """

    rc, output = openbmctool_execute_command(
        "fru print", print_output=False, ignore_err=False
    )
    if parse_json:
        return gm.json_loads_multiple(output)
    else:
        return output


def get_fru_list(parse_json=True):
    r"""
    Get the output of the fru list command and return it either as raw JSON
    data or as a list of dictionaries.

    Example robot code:

    ${fru_list}=  Get Fru List  parse_json=${False}
    Log to Console  ${fru_list}

    Example result (excerpt):

    {
      "data": {
        "/xyz/openbmc_project/inventory/system": {
          "AssetTag": "",
          "BuildDate": "",
          "Cached": false,
          "FieldReplaceable": false,
          "Manufacturer": "",
          "Model": "xxxxxxxx",
          "PartNumber": "",
          "Present": true,
          "PrettyName": "",
          "SerialNumber": "13183FA"
        },
        "/xyz/openbmc_project/inventory/system/chassis": {
          "AirCooled": true,
          "WaterCooled": false
        },
    ...

    Example robot code:

    ${fru_list}=  Get Fru List
    Rprint Vars  fru_list  fmt=1

    Example result (excerpt):

    fru_list:
      fru_list[0]:
        [data]:
          [/xyz/openbmc_project/inventory/system]:
            [AssetTag]:          <blank>
            [BuildDate]:         <blank>
            [Cached]:            False
            [FieldReplaceable]:  False
            [Manufacturer]:      <blank>
            [Model]:             xxxxxxxx
            [PartNumber]:        <blank>
            [Present]:           True
            [PrettyName]:        <blank>
            [SerialNumber]:      13183FA
          [/xyz/openbmc_project/inventory/system/chassis]:
            [AirCooled]:         True
            [WaterCooled]:       False
    ...

    Description of argument(s):
    parse_json                      Indicates that the raw JSON data should
                                    parsed into a list of dictionaries.
    """

    rc, output = openbmctool_execute_command(
        "fru list", print_output=False, ignore_err=False
    )
    if parse_json:
        return gm.json_loads_multiple(output)
    else:
        return output


def get_sensors_print():
    r"""
    Get the output of the sensors print command and return as a list of
    dictionaries.

    Example robot code:

    ${sensors_print}=  Get Sensors Print
    Rprint Vars  sensors_print  fmt=1

    Example result (excerpt):

    sensors_print:
      sensors_print[0]:
        [sensor]:                OCC0
        [type]:                  Discrete
        [units]:                 N/A
        [value]:                 Active
        [target]:                Active
      sensors_print[1]:
        [sensor]:                OCC1
        [type]:                  Discrete
        [units]:                 N/A
        [value]:                 Active
        [target]:                Active
    ...
    """
    rc, output = openbmctool_execute_command(
        "sensors print", print_output=False, ignore_err=False
    )
    # Example value for output (partial):
    # sensor                 | type         | units     | value    | target
    # OCC0                   | Discrete     | N/A       | Active   | Active
    # OCC1                   | Discrete     | N/A       | Active   | Active

    return vf.outbuf_to_report(output, field_delim="|")


def get_sensors_list():
    r"""
    Get the output of the sensors list command and return as a list of
    dictionaries.

    Example robot code:

    ${sensors_list}=  Get Sensors List
    Rprint Vars  sensors_list  fmt=1

    Example result (excerpt):

    sensors_list:
      sensors_list[0]:
        [sensor]:                OCC0
        [type]:                  Discrete
        [units]:                 N/A
        [value]:                 Active
        [target]:                Active
      sensors_list[1]:
        [sensor]:                OCC1
        [type]:                  Discrete
        [units]:                 N/A
        [value]:                 Active
        [target]:                Active
    ...
    """
    rc, output = openbmctool_execute_command(
        "sensors list", print_output=False, ignore_err=False
    )
    # Example value for output (partial):
    # sensor                 | type         | units     | value    | target
    # OCC0                   | Discrete     | N/A       | Active   | Active
    # OCC1                   | Discrete     | N/A       | Active   | Active

    return vf.outbuf_to_report(output, field_delim="|")


def get_openbmctool_version():
    r"""
    Get the openbmctool.py version and return it.

    Example robot code:
    ${openbmctool_version}=  Get Openbmctool Version
    Rprint Vars  openbmctool_version

    Example result (excerpt):
    openbmctool_version:         1.06
    """
    rc, output = openbmctool_execute_command(
        "-V | cut -f 2 -d ' '", print_output=False, ignore_err=False
    )
    return output


def service_data_files():
    r"""
    Return a complete list of file names that are expected to be created by
    the collect_service_data command.
    """

    return [
        "inventory.txt",
        "sensorReadings.txt",
        "ledStatus.txt",
        "SELshortlist.txt",
        "parsedSELs.txt",
        "bmcFullRaw.txt",
    ]


def collect_service_data(verify=False):
    r"""
    Run the collect_service_data command and return a list of files generated
    by the command.

    Description of argument(s):
    verify                          If set, verify that all files which can be
                                    created by collect_service_data did, in
                                    fact, get created.
    """

    # Route the output of collect_service_data to a file for easier parsing.
    temp = tempfile.NamedTemporaryFile()
    temp_file_path = temp.name
    openbmctool_execute_command(
        "collect_service_data > " + temp_file_path, ignore_err=False
    )
    # Isolate the file paths in the collect_service_data output.  We're
    # looking for output lines like this from which to extract the file paths:
    # Inventory collected and stored in /tmp/dummy--2018-09-26_17.59.18/inventory.txt
    rc, file_paths = gc.shell_cmd(
        "egrep 'collected and' " + temp_file_path
        # + " | sed -re 's#.*/tmp#/tmp#g'",
        + " | sed -re 's#[^/]*/#/#'",
        quiet=1,
        print_output=0,
    )
    # Example file_paths value:
    # /tmp/dummy--2018-09-26_17.59.18/inventory.txt
    # /tmp/dummy--2018-09-26_17.59.18/sensorReadings.txt
    # etc.
    # Convert from output to list.
    collect_service_data_file_paths = list(
        filter(None, file_paths.split("\n"))
    )
    if int(verify):
        # Create a list of files by stripping the dir names from the elements
        # of collect_service_data_file_paths.
        files_obtained = [
            re.sub(r".*/", "", file_path)
            for file_path in collect_service_data_file_paths
        ]
        files_expected = service_data_files()
        files_missing = list(set(files_expected) - set(files_obtained))
        if len(files_missing) > 0:
            gp.printn(
                "collect_service_data output:\n"
                + gm.file_to_str(temp_file_path)
            )
            err_msg = "The following files are missing from the list of files"
            err_msg += " returned by collect_service_data:\n"
            err_msg += gp.sprint_var(files_missing)
            err_msg += gp.sprint_var(collect_service_data_file_paths)
            BuiltIn().fail(gp.sprint_error(err_msg))

    return collect_service_data_file_paths


def health_check_fields():
    r"""
    Return a complete list of field names returned by the health_check command.
    """

    return ["hardware_status", "performance"]


def get_health_check(verify=False):
    r"""
    Get the health_check information and return as a dictionary.

    Example robot code:

    ${health_check}=  Get Health Check
    Rprint Vars  health_check  fmt=1

    Example result:

    health_check:
      [hardware_status]:         OK
      [performance]:             OK

    Description of argument(s):
    verify                          If set, verify that all all expected
                                    field_names are generated by the
                                    health_check command.
    """

    rc, output = openbmctool_execute_command(
        "health_check", print_output=False, ignore_err=False
    )
    health_check = vf.key_value_outbuf_to_dict(output, delim=":")
    if int(verify):
        err_msg = gv.valid_dict(health_check, health_check_fields())
        if err_msg != "":
            BuiltIn().fail(gp.sprint_error(err_msg))

    return health_check


def remote_logging_view_fields():
    r"""
    Return a complete list of field names returned by the logging
    remote_logging view command.
    """

    return ["Address", "Port"]


def get_remote_logging_view(verify=False):
    r"""
    Get the remote_logging view information and return as a dictionary.

    Example robot code:

    ${remote_logging_view}=  Get Remote Logging View
    Rprint Vars  remote_logging_view  fmt=1

    Example result:

    remote_logging_view:
      [Address]:                 <blank>
      [AddressFamily]:           xyz.openbmc_project.Network.Client.IPProtocol.IPv4
      [Port]:                    0

    Description of argument(s):
    verify                          If set, verify that all all expected field
                                    names are generated by the 'logging
                                    remote_logging view' command.
    """

    remote_logging_view = openbmctool_execute_command_json(
        "logging remote_logging view", print_output=False, ignore_err=False
    )

    if int(verify):
        err_msg = gv.valid_dict(
            remote_logging_view, remote_logging_view_fields()
        )
        if err_msg != "":
            BuiltIn().fail(gp.sprint_error(err_msg))

    return remote_logging_view


def network(sub_command, **options):
    r"""
    Run an openbmctool.py network command and return the results as a dictionary.

    Note that any valid network argument may be specified as a function argument.

    Example robot code:

    ${ip_records}=  Network  getIP  I=eth0
    Rprint Vars  ip_records

    Resulting output:

    ip_records:
      [/xyz/openbmc_project/network/eth0/ipv4/23d41d48]:
        [Address]:                  n.n.n.n
        [Gateway]:
        [Origin]:                   xyz.openbmc_project.Network.IP.AddressOrigin.Static
        [PrefixLength]:             24
        [Type]:                     xyz.openbmc_project.Network.IP.Protocol.IPv4
      [/xyz/openbmc_project/network/eth0/ipv4/24ba5feb]:
        [Address]:                  n.n.n.n
      (etc.)

    Description of argument(s):
    sub_command                     The sub-command accepted by the network
                                    command (e.g. "view-config", "getIP",
                                    etc.).
    options                         Zero or more options accepted by the network command.
    """

    if gm.python_version < gm.ordered_dict_version:
        new_options = collections.OrderedDict(options)
    else:
        new_options = options

    command_string = gc.create_command_string(
        "network " + sub_command, new_options
    )
    return openbmctool_execute_command_json(
        command_string, print_output=False, ignore_err=False
    )
