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