from __future__ import annotations

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

import yaml


ROOT = Path(__file__).resolve().parents[1]
DEFAULT_START_LINKS = ROOT / "plugins" / "1c" / "rag" / "official-docs" / "start-links.json"
DEFAULT_SOURCES = ROOT / "plugins" / "1c" / "rag" / "official-docs" / "sources.yaml"
DEFAULT_OUTPUT = ROOT / "reports" / "1c-official-docs-start-coverage.json"


def load_json(path: Path) -> dict[str, Any]:
    return json.loads(path.read_text(encoding="utf-8-sig")) if path.exists() else {}


def load_yaml(path: Path) -> dict[str, Any]:
    data = yaml.safe_load(path.read_text(encoding="utf-8"))
    return data if isinstance(data, dict) else {}


def check_coverage(start_links_path: Path, sources_path: Path) -> dict[str, Any]:
    start_links = load_json(start_links_path)
    sources_config = load_yaml(sources_path)
    source_urls = {str(item.get("url") or "") for item in sources_config.get("sources") or []}
    candidates = start_links.get("start_links") or []
    rows = []
    by_category: dict[str, dict[str, int]] = {}
    for item in candidates:
        category = str(item.get("category") or "unknown")
        active = str(item.get("url") or "") in source_urls
        by_category.setdefault(category, {"candidates": 0, "active": 0, "inactive": 0})
        by_category[category]["candidates"] += 1
        by_category[category]["active" if active else "inactive"] += 1
        rows.append({**item, "active": active})
    inactive = [item for item in rows if not item["active"]]
    counts = {
        "sources": len(source_urls),
        "candidates": len(rows),
        "active_candidates": sum(1 for item in rows if item["active"]),
        "inactive_candidates": len(inactive),
    }
    findings = []
    required_categories = {
        "dev_section",
        "dev_section_index",
        "developer_glossary",
        "development_standards",
        "methodical_support",
        "platform_doc",
    }
    for category in sorted(required_categories):
        stats = by_category.get(category) or {}
        if stats.get("active", 0) == 0:
            findings.append({"severity": "error", "message": f"no active source for required category {category}"})
    return {
        "schema": "onec_its_start_link_coverage.v1",
        "passed": not any(item["severity"] == "error" for item in findings),
        "start_links": str(start_links_path),
        "sources": str(sources_path),
        "counts": counts,
        "by_category": dict(sorted(by_category.items())),
        "findings": findings,
        "inactive_samples": inactive[:50],
    }


def main() -> int:
    parser = argparse.ArgumentParser(description="Compare discovered 1C:ITS start links with active sources.yaml seeds.")
    parser.add_argument("--start-links", type=Path, default=DEFAULT_START_LINKS)
    parser.add_argument("--sources", type=Path, default=DEFAULT_SOURCES)
    parser.add_argument("--output", type=Path, default=DEFAULT_OUTPUT)
    parser.add_argument("--print", action="store_true", dest="print_report")
    args = parser.parse_args()

    report = check_coverage(args.start_links, args.sources)
    args.output.parent.mkdir(parents=True, exist_ok=True)
    args.output.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
    if args.print_report:
        print(json.dumps(report, ensure_ascii=False, indent=2))
    return 0 if report["passed"] else 1


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