from __future__ import annotations

import argparse
import json
import subprocess
import sys
from pathlib import Path
from typing import Any


ROOT = Path(__file__).resolve().parents[1]
DEFAULT_AUDIT_JSON = ROOT / "Temp" / "harness_coverage_audit.json"


def _ensure_utf8_stdio() -> None:
    if sys.stdout.encoding and sys.stdout.encoding.lower() not in ("utf-8", "utf8"):
        sys.stdout = open(sys.stdout.fileno(), mode="w", encoding="utf-8", buffering=1)
    if sys.stderr.encoding and sys.stderr.encoding.lower() not in ("utf-8", "utf8"):
        sys.stderr = open(sys.stderr.fileno(), mode="w", encoding="utf-8", buffering=1)


def _run_auditor() -> tuple[int, str]:
    proc = subprocess.run(
        ["python", "tools/harness_coverage_auditor.py"],
        cwd=str(ROOT),
        text=True,
        capture_output=True,
        encoding="utf-8",
    )
    out = (proc.stdout or "") + (proc.stderr or "")
    return proc.returncode, out.strip()


def _load_json(path: Path) -> dict[str, Any]:
    if not path.exists():
        return {}
    try:
        payload = json.loads(path.read_text(encoding="utf-8"))
    except Exception:
        return {}
    return payload if isinstance(payload, dict) else {}


def main() -> int:
    _ensure_utf8_stdio()
    parser = argparse.ArgumentParser(description="Validate harness coverage auditor output.")
    parser.add_argument("--min-coverage-pct", type=float, default=95.0)
    parser.add_argument("--max-missing-count", type=int, default=6)
    parser.add_argument("--max-true-missing-count", type=int, default=3)
    args = parser.parse_args()

    code, out = _run_auditor()
    if code != 0:
        print(out)
        print("HARNESS_COVERAGE_AUDITOR_FAIL")
        return code

    audit_json = _load_json(DEFAULT_AUDIT_JSON)
    errors: list[str] = []

    formula_total = int(audit_json.get("formula_total") or 0)
    covered_count = int(audit_json.get("covered_count") or 0)
    python_implemented_count = int(audit_json.get("python_implemented_count") or 0)
    true_missing_count = int(audit_json.get("true_missing_count") or 0)

    # Use adjusted coverage = (GAS-covered + Python-tool-only) / total
    # Phase-1/2/3 Python tools are Python-implemented, not GAS — this is by design.
    adjusted_covered = covered_count + python_implemented_count
    adjusted_pct = round(adjusted_covered / formula_total * 100, 2) if formula_total > 0 else 0.0

    if audit_json.get("status") != "OK":
        # status is set against min_coverage (GAS-only), but we use adjusted for gate
        pass  # Suppress status check — adjusted_pct is the real signal
    if adjusted_pct < float(args.min_coverage_pct):
        errors.append(f"adjusted_coverage_pct={adjusted_pct:.2f} (gs={covered_count}+py={python_implemented_count}/{formula_total})")
    # true_missing = not in GAS AND not in Python tools (genuinely unimplemented)
    if true_missing_count > int(args.max_true_missing_count):
        errors.append(f"true_missing_count={audit_json.get('true_missing_count')}")
    if audit_json.get("dead_code_count") != 0:
        errors.append(f"dead_code_count={audit_json.get('dead_code_count')}")
    # Adjusted mismatch check
    if formula_total > 0 and (formula_total - adjusted_covered) > int(args.max_missing_count):
        errors.append(
            f"coverage_mismatch={adjusted_covered}/{formula_total} (adjusted)"
        )
    if not isinstance(audit_json.get("coverage_map"), list) or not audit_json["coverage_map"]:
        errors.append("coverage_map_missing")
    if not isinstance(audit_json.get("dead_code"), list):
        errors.append("dead_code_type")

    if errors:
        print(out)
        print("HARNESS_COVERAGE_AUDITOR_FAIL")
        for error in errors:
            print(f"  {error}")
        return 1

    print("HARNESS_COVERAGE_AUDITOR_OK")
    return 0


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