#!/usr/bin/env python3

import sphinxify
from cxxheaderparser.simple import parse_string
from cxxheaderparser.tokfmt import tokfmt

if __name__ == "__main__":
    with open("ntcore/src/main/native/include/wpi/nt/ntcore_cpp.hpp") as fp:
        data = parse_string(fp.read())

    for c in data.namespace.namespaces["wpi"].namespaces["nt"].classes:
        if c.class_decl.typename.format() == "struct PubSubOptions":
            params = []
            docs = []

            for f in c.fields:
                if f.static or f.name == "structSize":
                    continue

                if f.type.format() == "NT_Publisher":
                    params.append(
                        (
                            "std::optional<std::shared_ptr<wpi::nt::Publisher>>",
                            f.name,
                            f"{f.name}.has_value() ? {f.name}.value()->GetHandle() : {f.value.format()}",
                            "std::nullopt",
                        )
                    )
                else:
                    v = f.value.format()
                    if v == "DEFAULT_PERIODIC":
                        v = f"wpi::nt::PubSubOptions::{v}"
                    params.append((f.type, f.name, f.name, v))

                if f.doxygen:
                    docs.append(f"@param {f.name} {f.doxygen}")

            paramstr = ",\n        ".join(f"{t.format()} {n}" for t, n, _, _ in params)
            args = ",\n        ".join(f'py::arg("{n}") = {v}' for _, n, _, v in params)
            options = ",\n          ".join(f".{fn} = {n}" for _, fn, n, _ in params)

            doc = "\n            ".join(
                sphinxify.process_raw("\n".join(docs)).lstrip().splitlines()
            )

            print(f"""
      // autogenerated by gen-pubsub.py
      .def(py::init([](
        {paramstr}
      ) -> wpi::nt::PubSubOptions {{
        return wpi::nt::PubSubOptions{{
          {options}
        }};
      }}),
        py::kw_only(),
        {args},
        R"(
            {doc}
        )"
      )
            """.removeprefix("\n").rstrip())
