#!/usr/bin/env python3
"""Project CLI wrapper for {{ project_name }} (DDD edition).

Prefer a per-project CLI in `.rapidkit/cli.py` when present. Otherwise
provide helpful guidance to the developer rather than guessing environment
details.
"""

import importlib.util
import sys
import argparse
from pathlib import Path
from typing import Optional


def _missing_cli(name: str) -> None:
    print(f"❌ Missing project-local CLI (.rapidkit/cli.py) - can't run '{name}'")
    print("💡 If you're a new user run: rapidkit init  # create venv + install deps")
    sys.exit(127)


def _load_project_cli_module() -> Optional[object]:
    project_root = Path(__file__).resolve().parents[1]
    cli_file = project_root / ".rapidkit" / "cli.py"
    if not cli_file.exists():
        return None
    spec = importlib.util.spec_from_file_location("project_cli", str(cli_file))
    if spec is None or spec.loader is None:
        return None
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)  # type: ignore
    return module


_mod = _load_project_cli_module()


# Default placeholders -- call `_missing_cli` if the project-local CLI isn't
# available. These are real functions so linters don't complain.
def init() -> None:
    _missing_cli("init")


def dev() -> None:
    _missing_cli("dev")


def start() -> None:
    _missing_cli("start")


def build() -> None:
    _missing_cli("build")


def test() -> None:
    _missing_cli("test")


def lint() -> None:
    _missing_cli("lint")


def format() -> None:  # type: ignore[misc]
    _missing_cli("format")


def help_cmd() -> None:
    print("Usage: poetry run <command>  # (init|dev|start|build|test|lint|format)")


if _mod is not None:
    # prefer project-provided implementations when available
    init = getattr(_mod, "init", init)
    dev = getattr(_mod, "dev", dev)
    start = getattr(_mod, "start", start)
    build = getattr(_mod, "build", build)
    test = getattr(_mod, "test", test)
    lint = getattr(_mod, "lint", lint)
    format = getattr(_mod, "format", format)
    help_cmd = getattr(_mod, "help_cmd", help_cmd)


_dev_impl = dev
_start_impl = start


def _runtime_kwargs_from_argv(argv: list[str]) -> dict:
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-p", "--port", type=int, dest="port")
    parser.add_argument("--host", dest="host")
    parser.add_argument("--allow-global-runtime", action="store_true", dest="allow_global_runtime")
    ns, _ = parser.parse_known_args(argv)

    kwargs = {}
    if ns.port is not None:
        kwargs["port"] = ns.port
    if ns.host is not None:
        kwargs["host"] = ns.host
    if ns.allow_global_runtime:
        kwargs["allow_global_runtime"] = True
    return kwargs


def dev() -> None:  # type: ignore[no-redef]
    kwargs = _runtime_kwargs_from_argv(sys.argv[1:])
    try:
        _dev_impl(**kwargs)
    except TypeError:
        _dev_impl()


def start() -> None:  # type: ignore[no-redef]
    kwargs = _runtime_kwargs_from_argv(sys.argv[1:])
    try:
        _start_impl(**kwargs)
    except TypeError:
        _start_impl()


def main() -> None:
    if len(sys.argv) < 2:
        help_cmd()
        return

    command = sys.argv[1]
    commands = {
        "init": init,
        "dev": dev,
        "start": start,
        "build": build,
        "test": test,
        "lint": lint,
        "format": format,
        "help": help_cmd,
    }

    if command in commands:
        if command in ("dev", "start"):
            parser = argparse.ArgumentParser(prog=f"poetry run {command}", add_help=False)
            parser.add_argument("-p", "--port", type=int, dest="port")
            parser.add_argument("--host", dest="host")
            parser.add_argument("--allow-global-runtime", action="store_true", dest="allow_global_runtime")
            ns, _ = parser.parse_known_args(sys.argv[2:])

            kwargs = {}
            if ns.port is not None:
                kwargs["port"] = ns.port
            if ns.host is not None:
                kwargs["host"] = ns.host
            if ns.allow_global_runtime:
                kwargs["allow_global_runtime"] = True

            try:
                commands[command](**kwargs)
            except TypeError:
                commands[command]()
        else:
            commands[command]()
    else:
        print(f"Unknown command: {command}")
        print("Run 'poetry run help' to see available commands.")
        sys.exit(1)


if __name__ == "__main__":
    main()
