#!/usr/bin/env python

r"""
BMC redfish utility functions.
"""

import json
from robot.libraries.BuiltIn import BuiltIn
import gen_print as gp


class bmc_redfish_utils(object):

    def __init__(self):
        r"""
        Initialize the bmc_redfish_utils object.
        """
        # Obtain a reference to the global redfish object.
        self._redfish_ = BuiltIn().get_library_instance('redfish')

    def get_redfish_session_info(self):
        r"""
        Returns redfish sessions info dictionary.

        {
            'key': 'yLXotJnrh5nDhXj5lLiH' ,
            'location': '/redfish/v1/SessionService/Sessions/nblYY4wlz0'
        }
        """
        session_dict = {
            "key": self._redfish_.get_session_key(),
            "location": self._redfish_.get_session_location()
        }
        return session_dict

    def get_attribute(self, resource_path, attribute):
        r"""
        Get resource attribute.

        Description of argument(s):
        resource_path               URI resource absolute path (e.g.
                                    "/redfish/v1/Systems/1").
        attribute                   Name of the attribute (e.g. 'PowerState').
        """

        resp = self._redfish_.get(resource_path)
        if attribute in resp.dict:
            return resp.dict[attribute]

        return None

    def get_properties(self, resource_path):
        r"""
        Returns dictionary of attributes for the resource.

        Description of argument(s):
        resource_path               URI resource absolute path (e.g.
                                    "/redfish/v1/Systems/1").
        """

        resp = self._redfish_.get(resource_path)
        return resp.dict

    def get_target_actions(self, resource_path, target_attribute):
        r"""
        Returns resource target entry of the searched target attribute.

        Description of argument(s):
        resource_path      URI resource absolute path
                           (e.g. "/redfish/v1/Systems/system").
        target_attribute   Name of the attribute (e.g. 'ComputerSystem.Reset').

        Example:
         "Actions": {
         "#ComputerSystem.Reset": {
          "ResetType@Redfish.AllowableValues": [
            "On",
            "ForceOff",
            "GracefulRestart",
            "GracefulShutdown"
          ],
          "target": "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"
          }
         }
        """

        global target_list
        target_list = []

        resp_dict = self.get_attribute(resource_path, "Actions")
        if resp_dict is None:
            return None

        # Recursively search the "target" key in the nested dictionary.
        # Populate the target_list of target entries.
        self.get_key_value_nested_dict(resp_dict, "target")

        # Return the matching target URL entry.
        for target in target_list:
            # target "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"
            if target_attribute in target:
                return target

        return None

    def get_member_list(self, resource_path):
        r"""
        Perform a GET list request and return available members entries.

        Description of argument(s):
        resource_path  URI resource absolute path
                       (e.g. "/redfish/v1/SessionService/Sessions").

        "Members": [
            {
              "@odata.id": "/redfish/v1/SessionService/Sessions/Z5HummWPZ7"
            }
            {
              "@odata.id": "/redfish/v1/SessionService/Sessions/46CmQmEL7H"
            }
          ],
        """

        member_list = []
        resp_list_dict = self.get_attribute(resource_path, "Members")
        if resp_list_dict is None:
            return member_list

        for member_id in range(0, len(resp_list_dict)):
            member_list.append(resp_list_dict[member_id]["@odata.id"])

        return member_list

    def list_request(self, resource_path):
        r"""
        Perform a GET list request and return available resource paths.

        Description of argument(s):
        resource_path  URI resource absolute path
                       (e.g. "/redfish/v1/SessionService/Sessions").
        """

        gp.qprint_executing(style=gp.func_line_style_short)

        # Set quiet variable to keep subordinate get() calls quiet.
        quiet = 1

        global resource_list
        resource_list = []
        self._rest_response_ = \
            self._redfish_.get(resource_path,
                               valid_status_codes=[200, 404, 500])

        # Return empty list.
        if self._rest_response_.status != 200:
            return resource_list

        self.walk_nested_dict(self._rest_response_.dict)

        if not resource_list:
            return uri_path

        for resource in resource_list:
            self._rest_response_ = \
                self._redfish_.get(resource,
                                   valid_status_codes=[200, 404, 500])
            if self._rest_response_.status != 200:
                continue
            self.walk_nested_dict(self._rest_response_.dict)

        resource_list.sort()
        return resource_list

    def enumerate_request(self, resource_path):
        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").
        """

        gp.qprint_executing(style=gp.func_line_style_short)

        # Set quiet variable to keep subordinate get() calls quiet.
        quiet = 1

        url_list = self.list_request(resource_path)

        resource_dict = {}

        # Return empty dict.
        if not url_list:
            return resource_dict

        for resource in url_list:
            # JsonSchemas data are not required in enumeration.
            # Example: '/redfish/v1/JsonSchemas/' and sub resources.
            if 'JsonSchemas' in resource:
                continue
            self._rest_response_ = \
                self._redfish_.get(resource,
                                   valid_status_codes=[200, 404, 500])
            if self._rest_response_.status != 200:
                continue
            resource_dict[resource] = self._rest_response_.dict

        return json.dumps(resource_dict, sort_keys=True,
                          indent=4, separators=(',', ': '))

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

        Description of argument(s):
        data    Nested dictionary data from response message.
        """

        for key, value in data.items():
            if isinstance(value, dict):
                self.walk_nested_dict(value)
            else:
                if 'Members' == key:
                    if isinstance(value, list):
                        for index in value:
                            if index['@odata.id'] not in resource_list:
                                resource_list.append(index['@odata.id'])
                if '@odata.id' == key:
                    if value not in resource_list and not value.endswith('/'):
                        resource_list.append(value)

    def get_key_value_nested_dict(self, data, key):
        r"""
        Parse through the nested dictionary and get the searched key value.

        Description of argument(s):
        data    Nested dictionary data from response message.
        key     Search dictionary key element.
        """

        for k, v in data.items():
            if isinstance(v, dict):
                self.get_key_value_nested_dict(v, key)

            if k == key:
                target_list.append(v)
