from __future__ import annotations

import argparse
import json
import sys
import urllib.request
from pathlib import Path
from typing import Any


ROOT = Path(__file__).resolve().parents[1]
DEFAULT_BASE_URL = "http://docker.cin.su:8011"
DEFAULT_REPORT = ROOT / "reports" / "1c-access" / "upo_test-access-snapshot-bsp.json"


def rpc(base_url: str, method: str, payload: dict[str, Any], *, timeout: int) -> dict[str, Any]:
    body = json.dumps({"method": method, "payload": payload}, ensure_ascii=False).encode("utf-8")
    request = urllib.request.Request(
        base_url.rstrip("/") + "/rpc",
        data=body,
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    with urllib.request.urlopen(request, timeout=timeout) as response:
        data = json.loads(response.read().decode("utf-8"))
    if not isinstance(data, dict):
        return {"status": "error", "error": "response_not_object", "response": data}
    return data


def main() -> int:
    parser = argparse.ArgumentParser(description="Smoke-check 1C access snapshot extraction.")
    parser.add_argument("--adapter-url", default=DEFAULT_BASE_URL)
    parser.add_argument("--base-id", default="upo_test")
    parser.add_argument("--preset", default="bsp", choices=["bsp"])
    parser.add_argument("--no-preset", action="store_true", help="Do not send preset; verifies the adapter default extractor path.")
    parser.add_argument("--limit", type=int, default=5000)
    parser.add_argument("--max-effective-per-user", type=int, default=5000)
    parser.add_argument("--timeout", type=int, default=120)
    parser.add_argument("--report", type=Path, default=DEFAULT_REPORT)
    parser.add_argument("--json", action="store_true", help="Print full JSON response.")
    args = parser.parse_args()

    payload = {
        "base_id": args.base_id,
        "limit": args.limit,
        "timeout_seconds": args.timeout,
        "max_effective_permissions_per_user": args.max_effective_per_user,
    }
    if not args.no_preset:
        payload["preset"] = args.preset
    result = rpc(args.adapter_url, "access.snapshot.extract", payload, timeout=args.timeout + 10)
    args.report.parent.mkdir(parents=True, exist_ok=True)
    args.report.write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")

    if args.json:
        print(json.dumps(result, ensure_ascii=False, indent=2))
    else:
        print(
            json.dumps(
                {
                    "status": result.get("status"),
                    "base_id": result.get("base_id"),
                    "preset": result.get("preset"),
                    "counts": result.get("counts"),
                    "effective_permission_truncation": {
                        "users": (result.get("counts") or {}).get("effective_users_permissions_truncated") if isinstance(result.get("counts"), dict) else None,
                        "returned": (result.get("counts") or {}).get("effective_permissions_returned") if isinstance(result.get("counts"), dict) else None,
                        "total": (result.get("counts") or {}).get("effective_permissions_total") if isinstance(result.get("counts"), dict) else None,
                    },
                    "report": str(args.report),
                },
                ensure_ascii=False,
                indent=2,
            )
        )

    if result.get("status") != "ok":
        return 1
    counts = result.get("counts") if isinstance(result.get("counts"), dict) else {}
    return 0 if int(counts.get("effective_users") or 0) > 0 else 2


if __name__ == "__main__":
    raise SystemExit(main())
