# Source code for argus_api.helpers.generator

    from os import mkdir
    from os.path import join, exists, sep
    from re import sub

    from argus_api.helpers.log import log

    def write_endpoints_to_disk(endpoints, output, with_plugin_decorators=False) -> None:
        """Outputs the directory structure with all endpoints

        :param list endpoints: List of endpoints generated with build_endpoint_structure
        """
        EMPTY_INIT_FILE = ""

        log.info("Generating static API files to %s" % output)

        def find(key, dictionary):
            """Finds all occurances of a key in nested list
            """
            for k, v in dictionary.items():
                if k == key:
                    yield v
                elif isinstance(v, dict):
                    for result in find(key, v):
                        yield result
                elif isinstance(v, list):
                    for d in v:
                        for result in find(key, d):
                            yield result

        endpoints = [endpoint for endpoint in find("__METADATA__", endpoints)]

        def create_python_module(path):
            if not exists(join(*path)):
                mkdir(join(*path))
            with open(join(*(path + ["__init__.py"])), "w") as init:
                init.write(EMPTY_INIT_FILE)

        for endpoint in endpoints:
            path = [sep] + output.split(sep)

            # Create directory tree
            if not exists(join(*path)):
                mkdir(join(*path))
            with open(join(*(path + ["__init__.py"])), "w") as init:
                from time import time
                init.write(EMPTY_INIT_FILE + "\n__CREATED_AT__ = %f" % time())

            for directory in endpoint["__PATH__"]:
                path.append(directory)

                # Write file
                if directory == endpoint["__PATH__"][-1]:
                    log.info("Generating endpoint: %s" % "/".join(endpoint["__PATH__"][:-1]))
                    with open(join(*(path[:-1] + ["%s.py" % endpoint["__MODULE_NAME__"]])), "w+") as endpoint_file:
                        method_names = []
                        endpoint_request_methods = []

                        # Never print the same method twice
                        for method in endpoint["__REQUEST_METHODS__"]:
                            if method.name not in method_names:
                                endpoint_request_methods.append(method)
                            method_names.append(method.name)

                        # Write endpoint templates to file, and decorate them
                        # with the plugin command registration decorator if with_plugin_decorators=True
                        endpoint_file.write( "\n".join(
                            ['"""Autogenerated API"""'] +
                            ["import requests"] +
                            ["from argus_cli.plugin import register_command"] +
                            [""] +
                            [""] +
                            [
                                ("@register_command(extending=({path}))".format(
                                    path="'%s'" % "','".join(endpoint["__PATH__"])
                                ) if with_plugin_decorators else "") +
                                request_method.to_template
                                for request_method in endpoint_request_methods
                            ])
                        )
                    log.info("Generating test helpers for endpoint: %s" % "/".join(endpoint["__PATH__"][:-1]))

                    # Create a directory for test decorators
                    create_python_module(path[:-1] + ["test_helpers"])
                    create_python_module(path[:-1] + ["test_helpers", endpoint["__MODULE_NAME__"]])
                    for request_method in endpoint["__REQUEST_METHODS__"]:
                        test_helper_path = path[:-1] + ["test_helpers", endpoint["__MODULE_NAME__"], "%s.py" % request_method.name]
                        # create_python_module(test_helper_path)
                        with open(join(*test_helper_path), "w") as test_helper:
                            test_helper.write(
                                '\n'.join(
                                    [
                                        request_method.decorator_template(200),
                                        request_method.decorator_template(401),
                                        request_method.decorator_template(403),
                                        request_method.decorator_template(404),
                                    ])
                                )

                else:
                    # Create directory tree
                    create_python_module(path)