#!/usr/bin/env python3
"""Repair installed TransformerLab plugin manifests from the pinned source manifest."""

from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path


def load_json(path: Path) -> dict:
    with path.open("r", encoding="utf-8") as handle:
        return json.load(handle)


def write_json(path: Path, payload: dict) -> None:
    with path.open("w", encoding="utf-8") as handle:
        json.dump(payload, handle, indent=2, sort_keys=False)
        handle.write("\n")


def candidate_manifest_paths(root: Path, plugin: str) -> list[Path]:
    candidates = []
    patterns = [
        f"workspace/plugins/{plugin}/index.json",
        f"orgs/*/workspace/plugins/{plugin}/index.json",
        f"orgs/*/plugins/{plugin}/index.json",
    ]
    for pattern in patterns:
        candidates.extend(root.glob(pattern))
    unique = []
    seen = set()
    for path in candidates:
        resolved = path.resolve()
        if resolved in seen:
            continue
        seen.add(resolved)
        unique.append(path)
    return unique


def repair_manifest(path: Path, required_supports: list[str], source_supports: list[str]) -> bool:
    payload = load_json(path)
    existing = payload.get("supports", [])
    if not isinstance(existing, list):
        existing = []

    desired = []
    seen = set()
    for item in source_supports:
        if isinstance(item, str) and item not in seen:
            desired.append(item)
            seen.add(item)
    for item in required_supports:
        if item not in seen:
            desired.append(item)
            seen.add(item)

    if existing == desired:
        return False

    payload["supports"] = desired
    write_json(path, payload)
    return True


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--transformerlab-dir", required=True)
    parser.add_argument("--plugin", required=True)
    parser.add_argument("--required-support", action="append", default=[])
    args = parser.parse_args()

    root = Path(args.transformerlab_dir).expanduser().resolve()
    source_manifest = root / "src" / "transformerlab" / "plugins" / args.plugin / "index.json"
    if not source_manifest.exists():
        print(f"missing source plugin manifest: {source_manifest}", file=sys.stderr)
        return 1

    source_payload = load_json(source_manifest)
    source_supports = source_payload.get("supports", [])
    if not isinstance(source_supports, list):
        print(f"invalid supports array in {source_manifest}", file=sys.stderr)
        return 1

    missing_required = [item for item in args.required_support if item not in source_supports]
    if missing_required:
        print(
            f"source plugin manifest {source_manifest} is missing required supports: {', '.join(missing_required)}",
            file=sys.stderr,
        )
        return 1

    updated = 0
    for manifest in candidate_manifest_paths(root, args.plugin):
        if repair_manifest(manifest, args.required_support, source_supports):
            updated += 1
            print(f"repaired {manifest}")

    if updated == 0:
        print(f"no installed {args.plugin} manifests needed repair")
    return 0


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