"""Create the two AuthV2 golden test projects in one workspace (certification fixtures).

Creates, through the normal ProjectService path, a project named:
    AuthV2 Golden Simple   (simple roles: owner plus workspace admin)
    AuthV2 Golden Complex  (multi-role and suspension cases; populate roles separately)

Side effects (this is the real create path, not a stub):
- queues repository creation, which is asynchronous;
- the project setup pipeline then provisions default auth (roles, Cloud app, config);
- counts against the workspace's project quota.

Idempotent: a project with the same name in the workspace is reported and not re-created.
Dry run is the default. Nothing is created without --apply.

After the setup pipeline finishes, run the normal plan, apply, and shadow steps on the new
project IDs. This script does not change authorization state.

Usage (P2HS-BE root, same .env as the API):

    python -m scripts.authz_v2_create_golden_projects --workspace-id <uuid>
    python -m scripts.authz_v2_create_golden_projects --workspace-id <uuid> --apply
"""

from __future__ import annotations

import argparse
import asyncio
import json
import sys
from uuid import UUID

from src.core.orm_import import import_all_orm_models

import_all_orm_models()

GOLDEN = {
    "AuthV2 Golden Simple": "Authorization v2 golden fixture: simple roles.",
    "AuthV2 Golden Complex": "Authorization v2 golden fixture: multi-role and suspension cases.",
}


async def _run(workspace_id: UUID, apply: bool, suffix: str = "") -> int:
    from sqlalchemy import select
    from src.core.database import async_session_factory
    from src.domain.projects.models import Project
    from src.domain.projects.router import get_project_service, get_workspace_facade
    from src.domain.workspaces.models import Workspace

    golden = {f"{name}{suffix}": description for name, description in GOLDEN.items()}
    results: list[dict] = []
    async with async_session_factory() as db:
        workspace = (
            await db.execute(select(Workspace).where(Workspace.id == workspace_id))
        ).scalar_one_or_none()
        if workspace is None or workspace.owner_id is None:
            print(f"[error] workspace {workspace_id} not found or has no owner", file=sys.stderr)
            return 2

        existing = {
            p.name: p
            for p in (
                await db.execute(select(Project).where(Project.workspace_id == workspace_id))
            ).scalars().all()
            if p.name in golden
        }

        for name, description in golden.items():
            entry = {"name": name}
            if name in existing:
                entry.update(result="EXISTS", project_id=str(existing[name].id),
                             written=False)
                results.append(entry)
                continue
            if not apply:
                entry.update(result="WOULD_CREATE", project_id=None, written=False)
                results.append(entry)
                continue
            try:
                service = await get_project_service(db, await get_workspace_facade(db))
                project = await service.create_project(
                    workspace_id=workspace_id,
                    name=name,
                    project_type=None,
                    description=description,
                    user_id=workspace.owner_id,
                    intent="authorization v2 golden fixture",
                    skip_discovery=True,
                )
                await db.commit()
                entry.update(result="CREATED", project_id=str(project.id), written=True)
            except Exception as exc:  # report and continue with the other project
                await db.rollback()
                entry.update(result="ERROR",
                             reason=f"{type(exc).__name__}:{str(exc)[:200]}",
                             project_id=None, written=False)
            results.append(entry)

    mode = "APPLY" if apply else "DRY RUN"
    for r in results:
        print(f"{r['name']:<24} {r['result']:<12} {r.get('project_id') or '-'}"
              f"  {r.get('reason', '')}")
    print(f"\n[{mode}] {len(results)} requested, "
          f"{sum(1 for r in results if r['written'])} created.")
    print(json.dumps({r["name"]: r.get("project_id") for r in results}, indent=2))
    return 1 if any(r["result"] == "ERROR" for r in results) else 0


def main() -> None:
    parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
    parser.add_argument("--workspace-id", type=UUID, required=True)
    parser.add_argument("--suffix", default="",
                        help="append to each fixture name, e.g. ' 2' for a new pair")
    parser.add_argument("--apply", action="store_true",
                        help="create the projects (default: dry run)")
    args = parser.parse_args()
    sys.exit(asyncio.run(_run(args.workspace_id, args.apply, args.suffix)))


if __name__ == "__main__":
    main()
