#!/usr/bin/env python3
"""Validate the project Skill manifest and local Markdown links."""

from __future__ import annotations

import argparse
import csv
import json
import re
from pathlib import Path

ROOT = Path(__file__).resolve().parents[2]
SKILLS = ROOT / "standards-stack/agent-skills/skills"
WIKI = ROOT / "standards-stack/llm-wiki"
MANIFEST = ROOT / "standards-stack/agent-skills"
LINK = re.compile(r"(?<!!)\[[^\]]+\]\(([^)]+)\)")
FRONTMATTER_FIELD = re.compile(r"^(name|description):\s*\S", re.MULTILINE)


def rows(path: Path, delimiter: str) -> list[dict[str, str]]:
    with path.open(newline="", encoding="utf-8") as handle:
        return list(csv.DictReader(handle, delimiter=delimiter))


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--json", action="store_true")
    args = parser.parse_args()
    errors: list[str] = []
    skill_files = sorted(SKILLS.glob("*/SKILL.md"))
    wiki_files = sorted(WIKI.rglob("*.md"))
    csv_rows = rows(MANIFEST / "CODEX_TEAM_SKILL_MANIFEST.csv", ",")
    tsv_rows = rows(MANIFEST / "CODEX_TEAM_SKILL_MANIFEST.tsv", "\t")
    if csv_rows != tsv_rows:
        errors.append("CSV and TSV manifests differ")
    listed = [row["path"] for row in csv_rows]
    if len(listed) != len(set(listed)):
        errors.append("manifest has duplicate paths")
    expected = {str(path.relative_to(ROOT)) for path in skill_files}
    actual = set(listed)
    for missing in sorted(expected - actual):
        errors.append(f"skill absent from manifest: {missing}")
    for listed_path in sorted(actual - expected):
        if not (ROOT / listed_path).is_file():
            errors.append(f"manifest path missing: {listed_path}")
    names: dict[str, str] = {}
    checked_links = 0
    for path in skill_files:
        body = path.read_text(encoding="utf-8")
        parts = body.split("---", 2)
        fields = set(FRONTMATTER_FIELD.findall(parts[1])) if len(parts) == 3 and not parts[0].strip() else set()
        if fields != {"name", "description"}:
            errors.append(f"Skill frontmatter needs name and description: {path.relative_to(ROOT)}")
        name = re.search(r"^name:\s*(.+)$", parts[1], re.MULTILINE) if len(parts) == 3 else None
        if name:
            value = name.group(1).strip()
            if value in names:
                errors.append(f"duplicate Skill name {value}: {names[value]} and {path.relative_to(ROOT)}")
            names[value] = str(path.relative_to(ROOT))
    for path in skill_files + wiki_files:
        body = path.read_text(encoding="utf-8")
        for raw in LINK.findall(body):
            link = raw.split("#", 1)[0].split("?", 1)[0].strip("<>")
            if not link or link.startswith(("http:", "https:", "mailto:", "data:", "skill:")) or "{" in link:
                continue
            checked_links += 1
            if not (path.parent / link).exists() and not (ROOT / link).exists():
                errors.append(f"broken local link: {path.relative_to(ROOT)} -> {link}")
    report = {
        "skills": len(skill_files),
        "wiki_markdown_pages": len(wiki_files),
        "manifest_rows": len(csv_rows),
        "checked_local_links": checked_links,
        "errors": errors,
    }
    if args.json:
        print(json.dumps(report, ensure_ascii=False, indent=2))
    else:
        print(f"{report['skills']} Skills, {report['wiki_markdown_pages']} wiki pages, "
              f"{report['manifest_rows']} manifest rows, {checked_links} links; {len(errors)} errors")
        for error in errors:
            print(error)
    return 1 if errors else 0


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