"""Manual runner for the management-db step.

Creates the database user/schema and runs migrations against the backend
of an existing generated project.

Usage:
  uv run python pipeline/management-db/run.py --run-id bmi_calculator_application_1778480873055
  uv run python pipeline/management-db/run.py --backend-dir /path/to/project/backend
"""
from __future__ import annotations

import argparse
import sys
from pathlib import Path

# ── Path setup ────────────────────────────────────────────────────────────────
ROOT_DIR         = Path(__file__).resolve().parents[2]
MIGRATE_PIPELINE = Path(__file__).resolve().parent / "pipeline"

for _p in (str(ROOT_DIR), str(MIGRATE_PIPELINE)):
    if _p not in sys.path:
        sys.path.insert(0, _p)

try:
    from dotenv import load_dotenv  # type: ignore
    load_dotenv(ROOT_DIR / ".env", override=False)
except ImportError:
    pass

from shared.config import DB_ADMIN_USER, DB_ADMIN_PASSWORD  # noqa: E402
from shared.logging import get_logger                         # noqa: E402
from migrate_db_service import migrate_backend               # noqa: E402

logger = get_logger(__name__)

_DIVIDER = "─" * 55


def _find_project(run_id: str) -> Path:
    runs_dir = ROOT_DIR / "runs" / "outputs"
    if not runs_dir.exists():
        raise FileNotFoundError(f"No runs directory at {runs_dir}")
    exact = runs_dir / run_id
    if exact.is_dir():
        return exact
    matches = [d for d in runs_dir.iterdir() if d.is_dir() and d.name.endswith(f"_{run_id}")]
    if not matches:
        raise FileNotFoundError(f"No project found for run_id '{run_id}'")
    if len(matches) > 1:
        raise ValueError(f"Multiple matches for '{run_id}': {[d.name for d in matches]}")
    return matches[0]


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(
        description="Create database and run migrations for a generated backend.",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=__doc__,
    )
    parser.add_argument("--run-id", default=None,
                        help="Project slug or run ID (looked up in runs/outputs/).")
    parser.add_argument("--backend-dir", default=None,
                        help="Direct path to the backend directory.")
    parser.add_argument("--admin-user", default=None,
                        help=f"PostgreSQL superuser (overrides DB_ADMIN_USER={DB_ADMIN_USER!r}).")
    parser.add_argument("--admin-password", default=None,
                        help="Password for the superuser (overrides DB_ADMIN_PASSWORD).")
    parser.add_argument("--db-host", default=None,
                        help="Override DB_HOST for the migration connection (e.g. 127.0.0.1 via SSH tunnel).")
    args = parser.parse_args(argv)

    # ── Resolve backend dir ───────────────────────────────────────────────────
    try:
        if args.backend_dir:
            backend_dir = Path(args.backend_dir).expanduser().resolve()
        elif args.run_id:
            project_root = _find_project(args.run_id)
            backend_dir = project_root / "backend"
            print(f"  Project : {project_root}")
        else:
            print("ERROR: provide --run-id or --backend-dir", file=sys.stderr)
            return 1
    except (FileNotFoundError, ValueError) as exc:
        print(f"ERROR: {exc}", file=sys.stderr)
        return 1

    if not backend_dir.exists():
        print(f"ERROR: backend directory not found: {backend_dir}", file=sys.stderr)
        return 1

    admin_user     = args.admin_user or DB_ADMIN_USER
    admin_password = args.admin_password or DB_ADMIN_PASSWORD

    if not admin_user or not admin_password:
        print(
            "ERROR: admin credentials required — use --admin-user / --admin-password "
            "or set DB_ADMIN_USER / DB_ADMIN_PASSWORD in .env",
            file=sys.stderr,
        )
        return 1

    print(_DIVIDER)
    print("  management-db")
    print(_DIVIDER)
    print(f"  Backend    : {backend_dir}")
    print(f"  Admin user : {admin_user}")
    print(_DIVIDER)

    rc = 0
    try:
        migrate_backend(backend_dir, admin_user=admin_user, admin_password=admin_password, db_host=args.db_host or None)
        print(f"[management-db] Done → {backend_dir}")
    except Exception as exc:
        print(f"[management-db] FAILED: {exc}", file=sys.stderr)
        rc = 1

    print(_DIVIDER)
    print("  Done." if rc == 0 else "  Finished with errors.")
    print(_DIVIDER)
    return rc


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