#!/usr/bin/env python3
import json
import os

import requests

WARNING = '''/****************************************************************
 *                 READ THIS WARNING FIRST
 * This is an auto-generated header which contains definitions
 * for Redfish DMTF defined messages.
 * DO NOT modify this registry outside of running the
 * parse_registries.py script.  The definitions contained within
 * this file are owned by DMTF.  Any modifications to these files
 * should be first pushed to the relevant registry in the DMTF
 * github organization.
 ***************************************************************/'''

REGISTRY_HEADER = WARNING + '''
#pragma once
#include <registries.hpp>

// clang-format off

namespace redfish::registries::{}
{{
'''

SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))

include_path = os.path.realpath(
    os.path.join(
        SCRIPT_DIR,
        "..",
        "redfish-core",
        "include",
        "registries"))

proxies = {
    'https': os.environ.get("https_proxy", None)
}


def make_getter(dmtf_name, header_name, type_name):
    url = 'https://redfish.dmtf.org/registries/{}'.format(dmtf_name)
    dmtf = requests.get(url, proxies=proxies)
    dmtf.raise_for_status()
    json_file = json.loads(dmtf.text)
    path = os.path.join(include_path, header_name)
    return (path, json_file, type_name, url)


files = []
files.append(make_getter('Base.1.13.0.json',
                         'base_message_registry.hpp',
                         'base'))
files.append(make_getter('TaskEvent.1.0.3.json',
                         'task_event_message_registry.hpp',
                         'task_event'))
files.append(make_getter('ResourceEvent.1.0.3.json',
                         'resource_event_message_registry.hpp',
                         'resource_event'))

# Remove the old files
for file, json_dict, namespace, url in files:
    try:
        os.remove(file)
    except BaseException:
        print("{} not found".format(file))

    with open(file, 'w') as registry:
        registry.write(REGISTRY_HEADER.format(namespace))
        # Parse the Registry header info
        registry.write(
            "const Header header = {{\n"
            "    \"{json_dict[@Redfish.Copyright]}\",\n"
            "    \"{json_dict[@odata.type]}\",\n"
            "    \"{json_dict[Id]}\",\n"
            "    \"{json_dict[Name]}\",\n"
            "    \"{json_dict[Language]}\",\n"
            "    \"{json_dict[Description]}\",\n"
            "    \"{json_dict[RegistryPrefix]}\",\n"
            "    \"{json_dict[RegistryVersion]}\",\n"
            "    \"{json_dict[OwningEntity]}\",\n"
            "}};\n"
            "constexpr const char* url =\n"
            "    \"{url}\";\n"
            "\n"
            "constexpr std::array registry =\n"
            "{{\n".format(
                json_dict=json_dict,
                url=url,
            ))

        messages_sorted = sorted(json_dict["Messages"].items())
        for messageId, message in messages_sorted:
            registry.write(
                "    MessageEntry{{\n"
                "        \"{messageId}\",\n"
                "        {{\n"
                "            \"{message[Description]}\",\n"
                "            \"{message[Message]}\",\n"
                "            \"{message[MessageSeverity]}\",\n"
                "            {message[NumberOfArgs]},\n"
                "            {{".format(
                    messageId=messageId,
                    message=message
                ))
            paramTypes = message.get("ParamTypes")
            if paramTypes:
                for paramType in paramTypes:
                    registry.write(
                        "\n"
                        "                \"{}\",".format(paramType)
                    )
                registry.write("\n            },\n")
            else:
                registry.write("},\n")
            registry.write(
                "            \"{message[Resolution]}\",\n"
                "        }}}},\n".format(message=message))

        registry.write(
            "\n};\n"
            "\n"
            "enum class Index\n"
            "{\n"
        )
        for index, (messageId, message) in enumerate(messages_sorted):
            messageId = messageId[0].lower() + messageId[1:]
            registry.write(
                "    {} = {},\n".format(messageId, index))
        registry.write(
            "}};\n"
            "}} // namespace redfish::registries::{}\n"
            .format(namespace))


def get_privilege_string_from_list(privilege_list):
    privilege_string = "{{\n"
    for privilege_json in privilege_list:
        privileges = privilege_json["Privilege"]
        privilege_string += "    {"
        for privilege in privileges:
            if privilege == "NoAuth":
                continue
            privilege_string += "\""
            privilege_string += privilege
            privilege_string += "\",\n"
        if privilege != "NoAuth":
            privilege_string = privilege_string[:-2]
        privilege_string += "}"
        privilege_string += ",\n"
    privilege_string = privilege_string[:-2]
    privilege_string += "\n}}"
    return privilege_string


def get_variable_name_for_privilege_set(privilege_list):
    names = []
    for privilege_json in privilege_list:
        privileges = privilege_json["Privilege"]
        names.append("And".join(privileges))
    return "Or".join(names)


def make_privilege_registry():
    path, json_file, type_name, url = \
        make_getter('Redfish_1.3.0_PrivilegeRegistry.json',
                    'privilege_registry.hpp', 'privilege')
    with open(path, 'w') as registry:
        registry.write(
            "#pragma once\n"
            "{WARNING}\n"
            "// clang-format off\n"
            "\n"
            "#include <privileges.hpp>\n"
            "\n"
            "namespace redfish::privileges\n"
            "{{\n"
            .format(
                WARNING=WARNING,
                filename=os.path.basename(path)))

        privilege_dict = {}
        for mapping in json_file["Mappings"]:
            # first pass, identify all the unique privilege sets
            for operation, privilege_list in mapping["OperationMap"].items():
                privilege_dict[get_privilege_string_from_list(
                    privilege_list)] = (privilege_list, )
        for index, key in enumerate(privilege_dict):
            (privilege_list, ) = privilege_dict[key]
            name = get_variable_name_for_privilege_set(privilege_list)
            registry.write(
                "const std::array<Privileges, {length}> "
                "privilegeSet{name} = {key};\n"
                .format(length=len(privilege_list), name=name, key=key)
            )
            privilege_dict[key] = (privilege_list, name)

        for mapping in json_file["Mappings"]:
            entity = mapping["Entity"]
            registry.write("// {}\n".format(entity))
            for operation, privilege_list in mapping["OperationMap"].items():
                privilege_string = get_privilege_string_from_list(
                    privilege_list)
                operation = operation.lower()

                registry.write(
                    "const static auto& {}{} = privilegeSet{};\n".format(
                        operation,
                        entity,
                        privilege_dict[privilege_string][1]))
            registry.write("\n")
        registry.write(
            "} // namespace redfish::privileges\n"
            "// clang-format on\n")


make_privilege_registry()
