#!/usr/bin/env python3
from __future__ import annotations

import argparse
import importlib.util
import io
from contextlib import redirect_stderr, redirect_stdout
import sys
from pathlib import Path


def load_run_module():
    script_path = Path(__file__).with_name("run_moc_audit.py")
    spec = importlib.util.spec_from_file_location("run_moc_audit", script_path)
    module = importlib.util.module_from_spec(spec)
    assert spec.loader is not None
    spec.loader.exec_module(module)
    return module


def main() -> None:
    parser = argparse.ArgumentParser(description="監査に失敗する MOC の一覧を出す。")
    parser.add_argument(
        "--root",
        default="Brain/MOC",
        help="監査対象の MOC ディレクトリ。既定値は Brain/MOC",
    )
    parser.add_argument(
        "--count-only",
        action="store_true",
        help="失敗件数だけを表示する",
    )
    args = parser.parse_args()

    run_module = load_run_module()
    root = Path(args.root)
    failed: list[str] = []
    infra_errors: list[tuple[str, str]] = []

    for path in sorted(root.glob("*.md")):
        try:
            with redirect_stdout(io.StringIO()), redirect_stderr(io.StringIO()):
                run_module.module.audit_moc(str(path))
        except RuntimeError as exc:
            msg = str(exc)
            if "監査に失敗しました" in msg:
                failed.append(str(path))
            else:
                infra_errors.append((str(path), msg))
        except Exception as exc:
            infra_errors.append((str(path), str(exc)))

    if infra_errors:
        print(f"INFRA_ERROR_COUNT={len(infra_errors)}", file=sys.stderr)
        for path, msg in infra_errors:
            first_line = msg.split("\n")[0][:120]
            print(f"  INFRA_ERROR: {path}: {first_line}", file=sys.stderr)

    if args.count_only:
        print(f"FAIL_COUNT={len(failed)}")
        return

    for path in failed:
        print(path)
    print(f"FAIL_COUNT={len(failed)}")


if __name__ == "__main__":
    try:
        main()
    except Exception as exc:
        print(f"ERROR: {exc}", file=sys.stderr)
        sys.exit(1)
