#!/usr/bin/env fuchsia-vendored-python
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import json
import re
import textwrap
import sys


def usage():
    print(
        "Usage:\n"
        "  magma_h_gen.py INPUT OUTPUT\n"
        "    INPUT    json file containing the magma interface definition\n"
        "    OUTPUT   destination path for the magma header file to generate\n"
        "  Example: ./magma_h_gen.py ./magma.json ./magma.h\n"
        "  Generates the magma header based on a provided json definition.\n"
        "  Description fields are generated in the Doxygen format."
    )


# Generate a string for a comment with a Doxygen tag, wrapping text as necessary.
def format_comment(type, comment):
    wrap = 100
    prefix_first = "/// \\" + type + " "
    prefix_len = len(prefix_first)
    prefix_rest = "///".ljust(prefix_len)
    lines = textwrap.wrap(comment, wrap - prefix_len)
    formatted = [f"{prefix_first}{lines[0]}"]
    formatted.extend(f"{prefix_rest}{line}" for line in lines[1:])
    return "\n".join(formatted)


# Generate a string for a magma export object, including its comment block.
def format_export(export):
    # Verify no use of "struct" in types - these should use type_t instead.
    for arg in export["arguments"]:
        m = re.search(r"(.*)struct ([^\*]*)(\**)", arg["type"])
        if m:
            print(
                f'Error in {export["name"]}: Argument type "{arg["type"]}" appears to be a struct.'
                f' Did you mean to use "{m.group(1)}{m.group(2)}_t{m.group(3)}"?'
            )
            sys.exit(-1)
    # Leading comment
    lines = [f'///\n{format_comment("brief", export["description"])}']
    lines.extend(
        format_comment("param", f'{arg["name"]} {arg["description"]}')
        for arg in export["arguments"]
    )
    lines.append("///")
    # Function signature
    lines.append(f'MAGMA_EXPORT {export["type"]} {export["name"]}(')
    lines.append(
        ",\n".join(
            f'    {arg["type"]} {arg["name"]}' for arg in export["arguments"]
        )
    )
    lines[-1] = f"{lines[-1]});"
    lines.append("")
    return "\n".join(lines)


# License string for the top of the file.
def license():
    return (
        "// Copyright 2016 The Fuchsia Authors. All rights reserved.\n"
        "// Use of this source code is governed by a BSD-style license that can be\n"
        "// found in the LICENSE file.\n"
    )


def top_level_docs():
    return (
        "// Magma is the driver model for GPUs/NPUs on Fuchsia.\n"
        "//\n"
        '// Magma has two driver components: a hardware-specific library loaded into an "application"’s\n'
        '// address space ("client driver", sometimes known as "Installable client driver" or "ICD");\n'
        "// and a system driver that interfaces with the hardware. Magma is described in detail at [0].\n"
        "//\n"
        "// The Magma APIs are vendor independent. Some drivers may implement only the subset of the\n"
        "// APIs that are relevant. The format of data carried inside commands/command buffers is not\n"
        "// defined. Some APIs are explicitly extensible, such as magma_query, to allow for specific\n"
        "// vendor/driver needs.  Vendor specifics must be contained in a separate definitions file.\n"
        "//\n"
        "// Since client driver implementations may be written in a variety of languages (possibly C),\n"
        "// the Magma bindings have a C interface, and may be used to interact with both Magma and Sysmem.\n"
        "//\n"
        "// The Magma bindings are OS independent so a client driver targeting Magma can easily be built\n"
        "// for Fuchsia or Linux. On Fuchsia the APIs are backed by Zircon and FIDL; for virtualized Linux\n"
        "// they are backed by a virtualization transport (virtmagma). APIs prefixed by 'magma_virt_' are\n"
        "// for virtualization only.  32-bit and 64-bit builds are supported for virtualized clients.\n"
        "//\n"
        "// On Fuchsia the system driver is a separate process, so Magma APIs follow a feed forward design\n"
        "// where possible to allow for efficient pipelining of requests.\n"
        "//\n"
        "// [0] https://fuchsia.dev/fuchsia-src/contribute/governance/rfcs/0198_magma_api_design\n"
        "//\n"
    )


# Guard macro that goes at the beginning/end of the header (after license).
def guards(begin):
    macro = "LIB_MAGMA_MAGMA_H_"
    if begin:
        return f"#ifndef {macro}\n#define {macro}\n"
    return f"#endif  // {macro}"


# Begin/end C linkage scope.
def externs(begin):
    if begin:
        return '#if defined(__cplusplus)\nextern "C" {\n#endif\n'
    return "#if defined(__cplusplus)\n}\n#endif\n"


# Includes list.
def includes():
    return (
        "#include <lib/magma/magma_common_defs.h> // IWYU pragma: export\n"
        "#include <stdint.h>\n"
    )


# Warning comment about auto-generation.
def genwarning():
    return (
        "// NOTE: DO NOT EDIT THIS FILE!\n"
        "// It is automatically generated by //src/graphics/lib/magma/include/magma/magma_h_gen.py\n"
    )


def genformatoff():
    return "// clang-format off\n"


def ifchange():
    return "// LINT.IfChange"


def thenchange():
    return "// LINT.ThenChange(magma_common_defs.h:version)"


def main():
    if len(sys.argv) != 3:
        usage()
        return 2
    try:
        with open(sys.argv[1], "r") as file:
            with open(sys.argv[2], "w") as dest:
                magma = json.load(file)["magma-interface"]
                lines = [
                    license(),
                    top_level_docs(),
                    genwarning(),
                    genformatoff(),
                    guards(True),
                    includes(),
                    ifchange(),
                    externs(True),
                ]
                lines.extend(format_export(e) for e in magma["exports"])
                lines.append(externs(False))
                lines.append(thenchange())
                lines.append(guards(False))
                lines.append("")
                dest.write("\n".join(lines))
    except Exception as e:
        print(f"Error accessing files: {e}")
        usage()
        return 1


if __name__ == "__main__":
    sys.exit(main())
