#!/usr/bin/env python3
# /// script
# requires-python = ">=3.9"
# ///
"""
Warden Sweep: Create tracking issue.

Creates a GitHub issue summarizing the sweep results after verification
but before patching. Gives every PR a parent to reference and gives
reviewers a single place to see the full picture.

Usage:
    uv run create_issue.py <sweep-dir>

Stdout: JSON with issueUrl and issueNumber
Stderr: Progress lines

Idempotent: if issueUrl already exists in manifest, skips creation.
"""
from __future__ import annotations

import argparse
import json
import os
import subprocess
import sys
from typing import Any

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from _utils import (  # noqa: E402
    ensure_github_label,
    pr_number_from_url,
    read_json,
    read_jsonl,
    severity_badge,
    write_json,
)


def build_issue_body(
    run_id: str,
    scan_index: list[dict[str, Any]],
    all_findings: list[dict[str, Any]],
    verified: list[dict[str, Any]],
    rejected: list[dict[str, Any]],
) -> str:
    """Build the GitHub issue body markdown."""
    files_scanned = sum(1 for e in scan_index if e.get("status") == "complete")
    files_timed_out = sum(
        1 for e in scan_index
        if e.get("status") == "error" and e.get("error") == "timeout"
    )
    files_errored = sum(
        1 for e in scan_index
        if e.get("status") == "error" and e.get("error") != "timeout"
    )

    # Collect unique skills from scan index
    skills: set[str] = set()
    for entry in scan_index:
        for skill in entry.get("skills", []):
            skills.add(skill)

    lines = [
        f"## Warden Sweep `{run_id}`",
        "",
        "| Metric | Count |",
        "|--------|-------|",
        f"| Files scanned | {files_scanned} |",
        f"| Files timed out | {files_timed_out} |",
        f"| Files errored | {files_errored} |",
        f"| Total findings | {len(all_findings)} |",
        f"| Verified | {len(verified)} |",
        f"| Rejected | {len(rejected)} |",
        "",
    ]

    if verified:
        lines.append("### Verified Findings")
        lines.append("")
        lines.append("| Severity | Skill | File | Title |")
        lines.append("|----------|-------|------|-------|")
        for f in verified:
            sev = severity_badge(f.get("severity", "info"))
            skill = f.get("skill", "")
            file_path = f.get("file", "")
            start_line = f.get("startLine")
            location = f"{file_path}:{start_line}" if start_line else file_path
            title = f.get("title", "")
            lines.append(f"| {sev} | {skill} | `{location}` | {title} |")
        lines.append("")

    if skills:
        lines.append("### Skills Run")
        lines.append("")
        lines.append(", ".join(sorted(skills)))
        lines.append("")

    lines.append("> Generated by Warden Sweep. PRs referencing this issue will appear below.")

    return "\n".join(lines) + "\n"


def create_github_issue(title: str, body: str) -> dict[str, Any]:
    """Create a GitHub issue with the warden label. Returns issueUrl and issueNumber."""
    ensure_github_label("warden", "5319E7", "Automated fix from Warden Sweep")

    result = subprocess.run(
        [
            "gh", "issue", "create",
            "--label", "warden",
            "--title", title,
            "--body", body,
        ],
        capture_output=True,
        text=True,
        timeout=30,
    )

    if result.returncode != 0:
        raise RuntimeError(f"gh issue create failed: {result.stderr.strip()}")

    issue_url = result.stdout.strip()
    try:
        issue_number = int(pr_number_from_url(issue_url))
    except (ValueError, IndexError):
        raise RuntimeError(f"Could not parse issue number from gh output: {issue_url}")

    return {"issueUrl": issue_url, "issueNumber": issue_number}


def main() -> None:
    parser = argparse.ArgumentParser(
        description="Warden Sweep: Create tracking issue"
    )
    parser.add_argument("sweep_dir", help="Path to the sweep directory")
    args = parser.parse_args()

    sweep_dir = args.sweep_dir
    data_dir = os.path.join(sweep_dir, "data")
    manifest_path = os.path.join(data_dir, "manifest.json")

    if not os.path.isdir(sweep_dir):
        print(
            json.dumps({"error": f"Sweep directory not found: {sweep_dir}"}),
            file=sys.stdout,
        )
        sys.exit(1)

    manifest = read_json(manifest_path) or {}

    # Idempotency: if issue already exists, return existing values
    if manifest.get("issueUrl"):
        output = {
            "issueUrl": manifest["issueUrl"],
            "issueNumber": manifest.get("issueNumber", 0),
        }
        print(json.dumps(output))
        return

    run_id = manifest.get("runId", "unknown")

    # Read sweep data
    scan_index = read_jsonl(os.path.join(data_dir, "scan-index.jsonl"))
    all_findings = read_jsonl(os.path.join(data_dir, "all-findings.jsonl"))
    verified = read_jsonl(os.path.join(data_dir, "verified.jsonl"))
    rejected = read_jsonl(os.path.join(data_dir, "rejected.jsonl"))

    files_scanned = sum(1 for e in scan_index if e.get("status") == "complete")

    # Build issue
    title = f"Warden Sweep {run_id}: {len(verified)} findings across {files_scanned} files"
    body = build_issue_body(run_id, scan_index, all_findings, verified, rejected)

    print("Creating tracking issue...", file=sys.stderr)
    result = create_github_issue(title, body)
    print(f"Created issue: {result['issueUrl']}", file=sys.stderr)

    # Write issueUrl and issueNumber to manifest
    manifest["issueUrl"] = result["issueUrl"]
    manifest["issueNumber"] = result["issueNumber"]
    manifest.setdefault("phases", {})["issue"] = "complete"
    write_json(manifest_path, manifest)

    print(json.dumps(result))


if __name__ == "__main__":
    main()
