#!/usr/bin/env python3
"""GitHub target repo 只讀存在性探測。

此工具使用 `git ls-remote --heads` 檢查候選 GitHub repo 是否可讀。
它不 clone、不 fetch、不 push，也不寫入任何 remote。
"""

from __future__ import annotations

import argparse
import json
import subprocess
from pathlib import Path


def probe_candidate(candidate: str, timeout: int) -> dict[str, object]:
    url = f"https://github.com/{candidate}.git"
    try:
        result = subprocess.run(
            ["git", "ls-remote", "--heads", url],
            check=False,
            capture_output=True,
            text=True,
            timeout=timeout,
        )
    except subprocess.TimeoutExpired:
        return {
            "github_repo": candidate,
            "url_redacted": url,
            "status": "timeout",
            "head_count": 0,
            "heads": [],
            "error_summary": "git ls-remote timeout",
        }

    heads = []
    if result.returncode == 0:
        for line in result.stdout.splitlines():
            parts = line.split()
            if len(parts) != 2 or not parts[1].startswith("refs/heads/"):
                continue
            heads.append(
                {
                    "name": parts[1].removeprefix("refs/heads/"),
                    "sha": parts[0],
                }
            )
        status = "exists" if heads else "exists_empty_or_no_heads"
        error_summary = ""
    else:
        stderr = result.stderr.strip()
        if "Repository not found" in stderr:
            status = "not_found_or_private"
            error_summary = "GitHub 回應 repository not found；可能未建立或為 private 且未授權"
        else:
            status = "error"
            error_summary = stderr.splitlines()[-1] if stderr else "git ls-remote failed"

    return {
        "github_repo": candidate,
        "url_redacted": url,
        "status": status,
        "head_count": len(heads),
        "heads": heads,
        "error_summary": error_summary,
    }


def write_markdown(payload: dict[str, object], path: Path) -> None:
    lines = [
        "# GitHub Target Probe 快照",
        "",
        "| 項目 | 值 |",
        "|------|----|",
        f"| 狀態 | `{payload['status']}` |",
        f"| 候選 repo 數 | `{payload['candidate_count']}` |",
        f"| exists | `{payload['exists_count']}` |",
        f"| not found or private | `{payload['not_found_or_private_count']}` |",
        "",
        "## 候選 Repo",
        "",
        "| GitHub repo | status | heads | error |",
        "|-------------|--------|-------|-------|",
    ]
    for candidate in payload.get("candidates", []):
        if not isinstance(candidate, dict):
            continue
        lines.append(
            "| "
            + " | ".join(
                [
                    f"`{candidate.get('github_repo', '')}`",
                    f"`{candidate.get('status', '')}`",
                    f"`{candidate.get('head_count', 0)}`",
                    str(candidate.get("error_summary", "") or "無"),
                ]
            )
            + " |"
        )
    lines.extend(
        [
            "",
            "> 注意：`not_found_or_private` 只代表未授權 read-only probe 看不到，不等同確認不存在。",
            "",
        ]
    )
    path.write_text("\n".join(lines), encoding="utf-8")


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--candidate", action="append", required=True)
    parser.add_argument("--output-json", required=True)
    parser.add_argument("--output-md", required=True)
    parser.add_argument("--timeout", type=int, default=10)
    args = parser.parse_args()

    candidates = [probe_candidate(candidate, args.timeout) for candidate in args.candidate]
    exists_count = sum(1 for item in candidates if item["status"].startswith("exists"))
    not_found_count = sum(1 for item in candidates if item["status"] == "not_found_or_private")
    payload = {
        "schema_version": "github_target_probe_v1",
        "status": "ok",
        "candidate_count": len(candidates),
        "exists_count": exists_count,
        "not_found_or_private_count": not_found_count,
        "candidates": candidates,
    }
    Path(args.output_json).write_text(
        json.dumps(payload, ensure_ascii=False, indent=2) + "\n",
        encoding="utf-8",
    )
    write_markdown(payload, Path(args.output_md))
    return 0


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