#!/usr/bin/env python3

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

import sys
import re
import json
from redfish_plus import redfish_plus
from robot.libraries.BuiltIn import BuiltIn
from json.decoder import JSONDecodeError
from redfish.rest.v1 import InvalidCredentialsError

import func_args as fa
import gen_print as gp


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