#!/usr/bin/env python3
"""Run TUC's public deterministic preview as a small CI/agent gate."""

from __future__ import annotations

import argparse
import json
import sys
import urllib.error
import urllib.request
from pathlib import Path
from urllib.parse import urlsplit


DEFAULT_ENDPOINT = "https://ultimate-critic.fly.dev/api/v1/public/preview"
EXIT_BY_VERDICT = {"pass": 0, "fail": 1, "insufficient_evidence": 2}


def parser() -> argparse.ArgumentParser:
    value = argparse.ArgumentParser(
        description="Check one text, code, or JSON artifact with TUC's no-key public preview.",
    )
    value.add_argument("artifact", help="Artifact file path, or - to read from stdin.")
    value.add_argument("--type", choices=("text", "code", "json"), required=True, dest="artifact_type")
    value.add_argument("--task", required=True, help="The original task, between 10 and 2,000 characters.")
    value.add_argument("--requirement", action="append", default=[], help="A requirement to check. May be repeated up to 12 times.")
    value.add_argument("--endpoint", default=DEFAULT_ENDPOINT, help="Preview endpoint; HTTPS is required except for localhost tests.")
    value.add_argument("--timeout", type=float, default=30.0)
    value.add_argument("--json", action="store_true", dest="json_output", help="Print the complete JSON response.")
    return value


def validate_endpoint(value: str) -> str:
    parsed = urlsplit(value)
    local_http = parsed.scheme == "http" and parsed.hostname in {"127.0.0.1", "localhost", "::1"}
    if parsed.scheme != "https" and not local_http:
        raise ValueError("endpoint must use HTTPS (HTTP is allowed only for localhost)")
    if not parsed.netloc:
        raise ValueError("endpoint must be an absolute URL")
    return value


def read_artifact(value: str) -> str:
    content = sys.stdin.read() if value == "-" else Path(value).read_text(encoding="utf-8")
    if not content:
        raise ValueError("artifact must not be empty")
    if len(content) > 10_000:
        raise ValueError("artifact exceeds the public preview limit of 10,000 characters")
    return content


def build_payload(args: argparse.Namespace, artifact: str) -> dict:
    task = args.task.strip()
    requirements = [item.strip() for item in args.requirement]
    if not 10 <= len(task) <= 2_000:
        raise ValueError("task must contain 10 to 2,000 characters")
    if len(requirements) > 12 or any(not item or len(item) > 500 for item in requirements):
        raise ValueError("use up to 12 non-empty requirements of at most 500 characters each")
    if args.artifact_type == "json":
        parsed = json.loads(artifact)
        if not isinstance(parsed, (dict, list)):
            raise ValueError("JSON artifacts must contain an object or array")
    return {
        "artifact_type": args.artifact_type,
        "task": task,
        "requirements": requirements,
        "artifact": artifact,
    }


def request_preview(endpoint: str, payload: dict, timeout: float) -> dict:
    request = urllib.request.Request(
        validate_endpoint(endpoint),
        data=json.dumps(payload, separators=(",", ":")).encode("utf-8"),
        headers={"Content-Type": "application/json; charset=utf-8", "User-Agent": "TUC-Preview-Gate/1.0"},
        method="POST",
    )
    with urllib.request.urlopen(request, timeout=timeout) as response:
        result = json.load(response)
    if result.get("mode") != "deterministic_no_retention" or result.get("retained") is not False:
        raise ValueError("endpoint did not return the public no-retention contract")
    return result


def print_summary(result: dict) -> str:
    evaluation = result.get("evaluation", {})
    overall = evaluation.get("overall", {})
    findings = evaluation.get("findings", [])
    lines = [
        f"verdict={overall.get('verdict', 'unknown')}",
        f"score={overall.get('score', 'unknown')}",
        f"findings={len(findings)}",
    ]
    for finding in findings:
        lines.append(f"- {str(finding.get('severity', 'unknown')).upper()}: {finding.get('title', 'Untitled finding')}")
    return "\n".join(lines)


def main(argv: list[str] | None = None) -> int:
    args = parser().parse_args(argv)
    try:
        payload = build_payload(args, read_artifact(args.artifact))
        result = request_preview(args.endpoint, payload, args.timeout)
        verdict = result.get("evaluation", {}).get("overall", {}).get("verdict")
        if verdict not in EXIT_BY_VERDICT:
            raise ValueError("response did not contain a supported verdict")
        print(json.dumps(result, indent=2, sort_keys=True) if args.json_output else print_summary(result))
        return EXIT_BY_VERDICT[verdict]
    except (OSError, ValueError, json.JSONDecodeError, urllib.error.URLError) as exc:
        print(f"tuc-preview-gate: {exc}", file=sys.stderr)
        return 3


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