"""``pmmanifest`` command-line interface: emit a manifest, or preview the GUI."""

from __future__ import annotations

import argparse
import importlib
import json
import sys

from ._generate import build_app_manifest, func_to_entry


def _load(target: str):
    """Resolve a ``package.module:function`` target to the callable."""
    module_name, sep, func_name = target.partition(":")
    if not sep or not func_name:
        raise SystemExit(f"target must be 'module:function', got {target!r}")
    module = importlib.import_module(module_name)
    return getattr(module, func_name)


def main(argv=None):
    parser = argparse.ArgumentParser(
        prog="pmmanifest",
        description="Generate / preview PlayMolecule v2 manifests from function signatures.",
    )
    sub = parser.add_subparsers(dest="cmd", required=True)

    emit = sub.add_parser("emit", help="Print the v2 manifest for a function")
    emit.add_argument("target", help="module:function (e.g. myapp.app:systembuilder)")
    emit.add_argument("--function", default=None, help="override the dotted function path")

    srv = sub.add_parser("serve", help="Live RJSF GUI preview of a function's schema")
    srv.add_argument("target", help="module:function")
    srv.add_argument("--port", type=int, default=8000)

    args = parser.parse_args(argv)
    func = _load(args.target)

    if args.cmd == "emit":
        entry = func_to_entry(func, function=args.function)
        name = getattr(func, "__name__", "app")
        json.dump(build_app_manifest(name, [entry]), sys.stdout, indent=2)
        sys.stdout.write("\n")
    elif args.cmd == "serve":
        from ._serve import serve

        serve(func, port=args.port)


if __name__ == "__main__":
    main()
