#!/usr/bin/env python3

r"""
See class prolog below for details.
"""

import json
import re
import sys
from json.decoder import JSONDecodeError

import func_args as fa
import gen_print as gp
from redfish.rest.v1 import InvalidCredentialsError
from redfish_plus import redfish_plus
from robot.libraries.BuiltIn import BuiltIn

MTLS_ENABLED = BuiltIn().get_variable_value("${MTLS_ENABLED}")


class bmc_redfish(redfish_plus):
    r"""
    bmc_redfish is a child class of redfish_plus that is designed to provide
    benefits specifically for using redfish to communicate with an OpenBMC.

    See the prologs of the methods below for details.
    """

    def __init__(self, *args, **kwargs):
        r"""
        Do BMC-related redfish initialization.

        Presently, older versions of BMC code may not support redfish
        requests.  This can lead to unsightly error text being printed out for
        programs that may use lib/bmc_redfish_resource.robot even though they
        don't necessarily intend to make redfish requests.

        This class method will make an attempt to tolerate this situation.  At
        some future point, when all BMCs can be expected to support redfish,
        this class method may be considered for deletion.  If it is deleted,
        the self.__inited__ test code in the login() class method below should
        likewise be deleted.
        """
        self.__inited__ = False
        try:
            if MTLS_ENABLED == "True":
                self.__inited__ = True
            else:
                super(bmc_redfish, self).__init__(*args, **kwargs)
                self.__inited__ = True
        except ValueError as get_exception:
            except_type, except_value, except_traceback = sys.exc_info()
            regex = r"The HTTP status code was not valid:[\r\n]+status:[ ]+502"
            result = re.match(regex, str(except_value), flags=re.MULTILINE)
            if not result:
                gp.lprint_var(except_type)
                gp.lprint_varx("except_value", str(except_value))
                raise (get_exception)
        BuiltIn().set_global_variable("${REDFISH_SUPPORTED}", self.__inited__)
        BuiltIn().set_global_variable("${REDFISH_REST_SUPPORTED}", True)

    def login(self, *args, **kwargs):
        r"""
        Assign BMC default values for username, password and auth arguments
        and call parent class login method.

        Description of argument(s):
        args                        See parent class method prolog for details.
        kwargs                      See parent class method prolog for details.
        """

        if MTLS_ENABLED == "True":
            return None
        if not self.__inited__:
            message = "bmc_redfish.__init__() was never successfully run.  It "
            message += "is likely that the target BMC firmware code level "
            message += "does not support redfish.\n"
            raise ValueError(message)
        # Assign default values for username, password, auth where necessary.
        openbmc_username = BuiltIn().get_variable_value("${OPENBMC_USERNAME}")
        openbmc_password = BuiltIn().get_variable_value("${OPENBMC_PASSWORD}")
        username, args, kwargs = fa.pop_arg(openbmc_username, *args, **kwargs)
        password, args, kwargs = fa.pop_arg(openbmc_password, *args, **kwargs)
        auth, args, kwargs = fa.pop_arg("session", *args, **kwargs)

        try:
            super(bmc_redfish, self).login(
                username, password, auth, *args, **kwargs
            )
        # Handle InvalidCredentialsError.
        # (raise redfish.rest.v1.InvalidCredentialsError if not [200, 201, 202, 204])
        except InvalidCredentialsError:
            except_type, except_value, except_traceback = sys.exc_info()
            BuiltIn().log_to_console(str(except_type))
            BuiltIn().log_to_console(str(except_value))
            e_message = "Re-try login due to exception and "
            e_message += "it is likely error response from server side."
            BuiltIn().log_to_console(e_message)
            super(bmc_redfish, self).login(
                username, password, auth, *args, **kwargs
            )
        # Handle JSONDecodeError and others.
        except JSONDecodeError:
            except_type, except_value, except_traceback = sys.exc_info()
            BuiltIn().log_to_console(str(except_type))
            BuiltIn().log_to_console(str(except_value))
            e_message = "Re-try login due to JSONDecodeError exception and "
            e_message += "it is likely error response from server side."
            BuiltIn().log_to_console(e_message)
            super(bmc_redfish, self).login(
                username, password, auth, *args, **kwargs
            )
        except ValueError:
            except_type, except_value, except_traceback = sys.exc_info()
            BuiltIn().log_to_console(str(except_type))
            BuiltIn().log_to_console(str(except_value))
            e_message = "Unexpected exception."
            BuiltIn().log_to_console(e_message)

    def logout(self):
        if MTLS_ENABLED == "True":
            return None
        else:
            super(bmc_redfish, self).logout()

    def get_properties(self, *args, **kwargs):
        r"""
        Return dictionary of attributes for a given path.

        The difference between calling this function and calling get()
        directly is that this function returns ONLY the dictionary portion of
        the response object.

        Example robot code:

        ${properties}=  Get Properties  /redfish/v1/Systems/system/
        Rprint Vars  properties

        Output:

        properties:
          [PowerState]:      Off
          [Processors]:
            [@odata.id]:     /redfish/v1/Systems/system/Processors
          [SerialNumber]:    1234567
          ...

        Description of argument(s):
        args                        See parent class get() prolog for details.
        kwargs                      See parent class get() prolog for details.
        """

        resp = self.get(*args, **kwargs)
        return resp.dict if hasattr(resp, "dict") else {}

    def get_attribute(self, path, attribute, default=None, *args, **kwargs):
        r"""
        Get and return the named attribute from the properties for a given
        path.

        This method has the following advantages over calling get_properties
        directly:
        - The caller can specify a default value to be returned if the
          attribute does not exist.

        Example robot code:

        ${attribute}=  Get Attribute  /redfish/v1/AccountService
        ...  MaxPasswordLength  default=600
        Rprint Vars  attribute

        Output:

        attribute:           31

        Description of argument(s):
        path                        The path (e.g.
                                    "/redfish/v1/AccountService").
        attribute                   The name of the attribute to be retrieved
                                    (e.g. "MaxPasswordLength").
        default                     The default value to be returned if the
                                    attribute does not exist (e.g. "").
        args                        See parent class get() prolog for details.
        kwargs                      See parent class get() prolog for details.
        """

        return self.get_properties(path, *args, **kwargs).get(
            attribute, default
        )

    def get_session_info(self):
        r"""
        Get and return session info as a tuple consisting of session_key and
        session_location.
        """

        return self.get_session_key(), self.get_session_location()

    def enumerate(
        self, resource_path, return_json=1, include_dead_resources=False
    ):
        r"""
        Perform a GET enumerate request and return available resource paths.

        Description of argument(s):
        resource_path               URI resource absolute path (e.g. "/redfish/v1/SessionService/Sessions").
        return_json                 Indicates whether the result should be returned as a json string or as a
                                    dictionary.
        include_dead_resources      Check and return a list of dead/broken URI resources.
        """

        gp.qprint_executing(style=gp.func_line_style_short)
        # Set quiet variable to keep subordinate get() calls quiet.
        quiet = 1

        self.__result = {}
        # Variable to hold the pending list of resources for which enumeration is yet to be obtained.
        self.__pending_enumeration = set()
        self.__pending_enumeration.add(resource_path)

        # Variable having resources for which enumeration is completed.
        enumerated_resources = set()
        dead_resources = {}
        resources_to_be_enumerated = (resource_path,)
        while resources_to_be_enumerated:
            for resource in resources_to_be_enumerated:
                # JsonSchemas, SessionService or URLs containing # are not required in enumeration.
                # Example: '/redfish/v1/JsonSchemas/' and sub resources.
                #          '/redfish/v1/SessionService'
                #          '/redfish/v1/Managers/${MANAGER_ID}#/Oem'
                if (
                    ("JsonSchemas" in resource)
                    or ("SessionService" in resource)
                    or ("#" in resource)
                ):
                    continue

                self._rest_response_ = self.get(
                    resource, valid_status_codes=[200, 404, 500]
                )
                # Enumeration is done for available resources ignoring the ones for which response is not
                # obtained.
                if self._rest_response_.status != 200:
                    if include_dead_resources:
                        try:
                            dead_resources[self._rest_response_.status].append(
                                resource
                            )
                        except KeyError:
                            dead_resources[self._rest_response_.status] = [
                                resource
                            ]
                    continue
                self.walk_nested_dict(self._rest_response_.dict, url=resource)

            enumerated_resources.update(set(resources_to_be_enumerated))
            resources_to_be_enumerated = tuple(
                self.__pending_enumeration - enumerated_resources
            )

        if return_json:
            if include_dead_resources:
                return (
                    json.dumps(
                        self.__result,
                        sort_keys=True,
                        indent=4,
                        separators=(",", ": "),
                    ),
                    dead_resources,
                )
            else:
                return json.dumps(
                    self.__result,
                    sort_keys=True,
                    indent=4,
                    separators=(",", ": "),
                )
        else:
            if include_dead_resources:
                return self.__result, dead_resources
            else:
                return self.__result

    def walk_nested_dict(self, data, url=""):
        r"""
        Parse through the nested dictionary and get the resource id paths.

        Description of argument(s):
        data                        Nested dictionary data from response message.
        url                         Resource for which the response is obtained in data.
        """
        url = url.rstrip("/")

        for key, value in data.items():
            # Recursion if nested dictionary found.
            if isinstance(value, dict):
                self.walk_nested_dict(value)
            else:
                # Value contains a list of dictionaries having member data.
                if "Members" == key:
                    if isinstance(value, list):
                        for memberDict in value:
                            self.__pending_enumeration.add(
                                memberDict["@odata.id"]
                            )
                if "@odata.id" == key:
                    value = value.rstrip("/")
                    # Data for the given url.
                    if value == url:
                        self.__result[url] = data
                    # Data still needs to be looked up,
                    else:
                        self.__pending_enumeration.add(value)

    def get_members_list(self, resource_path, filter=None):
        r"""
        Return members list in a given URL.

        Description of argument(s):
        resource_path    URI resource absolute path (e.g. "/redfish/v1/AccountService/Accounts").
        filter           strings or regex

        /redfish/v1/AccountService/Accounts/
        {
            "@odata.id": "/redfish/v1/AccountService/Accounts",
            "@odata.type": "#ManagerAccountCollection.ManagerAccountCollection",
            "Description": "BMC User Accounts",
            "Members": [
                {
                    "@odata.id": "/redfish/v1/AccountService/Accounts/root"
                },
                {
                    "@odata.id": "/redfish/v1/AccountService/Accounts/admin"
                }
           ],
           "Members@odata.count": 2,
           "Name": "Accounts Collection"
        }

        Return list of members if no filter is applied as:
        ['/redfish/v1/AccountService/Accounts/root', "/redfish/v1/AccountService/Accounts/admin"]

        Return list of members if filter (e.g "root") is applied as:
        ['/redfish/v1/AccountService/Accounts/root']


        Calling from robot code:
           ${resp}=  Redfish.Get Members List  /redfish/v1/AccountService/Accounts
           ${resp}=  Redfish.Get Members List  /redfish/v1/AccountService/Accounts  filter=root
        """

        member_list = []
        self._rest_response_ = self.get(
            resource_path, valid_status_codes=[200]
        )

        try:
            for member in self._rest_response_.dict["Members"]:
                member_list.append(member["@odata.id"])
        except KeyError:
            # Non Members child objects at the top level, ignore.
            pass

        # Filter elements in the list and return matched elements.
        if filter is not None:
            regex = ".*/" + filter + "[^/]*$"
            return [x for x in member_list if re.match(regex, x)]

        return member_list
