#!/usr/bin/env python3
"""
Normalize gate artifact JSON schema — minimal `agent` field fix.

History: F-123..F-135 (13 features x 3 gate files = 39 files) were closed
with the wrong field name (`reviewer` instead of `agent`). `verify.sh`
rejects those files because it checks `obj.get('agent') == '<role>'`.

This script is idempotent: it adds `agent` from the legacy `reviewer`
field (when present and matching) without touching any other field.
Re-running it on an already-normalized file is a no-op. `stage` is not
required by `verify.sh`, so we leave it alone.

Usage:
  python3 scripts/fix_gate_schema.py                 # all artifacts
  python3 scripts/fix_gate_schema.py F-123 F-124     # specific features
  python3 scripts/fix_gate_schema.py --dry-run       # preview only
"""
from __future__ import annotations

import json
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
ARTIFACTS_DIR = ROOT / 'work' / 'artifacts'

FILE_TO_AGENT = {
    'reviewer.json': 'reviewer',
    'security.json': 'security',
    'qa.json': 'qa',
}


def normalize(feature_dir: Path, dry_run: bool = False) -> list[str]:
    """Normalize gate files in `feature_dir`. Returns list of changes made."""
    changes: list[str] = []
    fid = feature_dir.name
    for filename, expected_agent in FILE_TO_AGENT.items():
        path = feature_dir / filename
        if not path.is_file():
            continue
        try:
            data = json.loads(path.read_text(encoding='utf-8'))
        except Exception:
            continue

        if data.get('agent') == expected_agent:
            continue  # already correct, no-op

        legacy = data.get('reviewer')
        if isinstance(legacy, str) and legacy == expected_agent:
            data['agent'] = legacy
            changes.append(f"{fid}/{filename}: copied agent='{expected_agent}' from legacy 'reviewer' field")
        else:
            data['agent'] = expected_agent
            changes.append(f"{fid}/{filename}: set agent='{expected_agent}'")

        if not dry_run:
            path.write_text(
                json.dumps(data, indent=2, ensure_ascii=False) + '\n',
                encoding='utf-8',
            )
    return changes


def main() -> int:
    args = [a for a in sys.argv[1:] if not a.startswith('--')]
    dry_run = '--dry-run' in sys.argv

    if args:
        targets = [ARTIFACTS_DIR / a for a in args]
        for t in targets:
            if not t.is_dir():
                print(f"[WARN] {t} is not a directory, skipping")
        targets = [t for t in targets if t.is_dir()]
    else:
        targets = sorted(p for p in ARTIFACTS_DIR.iterdir() if p.is_dir())

    total_changes: list[str] = []
    for d in targets:
        total_changes.extend(normalize(d, dry_run=dry_run))

    if not total_changes:
        print('[OK] All gate files already conform to schema (agent field present)')
        return 0

    verb = 'Would fix' if dry_run else 'Fixed'
    print(f"{verb} {len(total_changes)} file(s):")
    for c in total_changes:
        print(f"  - {c}")
    return 0


if __name__ == '__main__':
    sys.exit(main())
