#!/usr/bin/env python3
"""Guard AWOOOI product navigation against orphaned frontend routes."""

from __future__ import annotations

import argparse
import json
import re
import sys
from pathlib import Path


ROUTE_RE = re.compile(r"href:\s*'([^']+)'")
ROUTE_LIST_RE = re.compile(r"(?:aliases|relatedPaths):\s*\[([^\]]*)\]")
LABEL_KEY_RE = re.compile(r"labelKey:\s*'([^']+)'")
QUOTED_RE = re.compile(r"'([^']+)'")


def locale_routes(root: Path) -> set[str]:
    app_root = root / "apps/web/src/app/[locale]"
    routes: set[str] = set()
    for page in app_root.rglob("page.tsx"):
        rel = page.relative_to(app_root)
        route_parts = rel.parts[:-1]
        if any(part.startswith("[") and part.endswith("]") for part in route_parts):
            continue
        route = "/" + "/".join(route_parts)
        routes.add("/" if route == "/" else route.rstrip("/"))
    return routes


def navigation_routes(root: Path) -> set[str]:
    source = (root / "apps/web/src/lib/navigation/product-ia.ts").read_text(
        encoding="utf-8"
    )
    routes = set(ROUTE_RE.findall(source))
    for match in ROUTE_LIST_RE.findall(source):
        routes.update(QUOTED_RE.findall(match))
    return {route.rstrip("/") or "/" for route in routes}


def navigation_label_keys(root: Path) -> set[str]:
    source = (root / "apps/web/src/lib/navigation/product-ia.ts").read_text(
        encoding="utf-8"
    )
    return set(LABEL_KEY_RE.findall(source))


def missing_nav_labels(root: Path, label_keys: set[str]) -> dict[str, list[str]]:
    missing: dict[str, list[str]] = {}
    for messages_file in sorted((root / "apps/web/messages").glob("*.json")):
        with messages_file.open(encoding="utf-8") as handle:
            payload = json.load(handle)
        nav = payload.get("nav") if isinstance(payload, dict) else None
        nav_keys = set(nav) if isinstance(nav, dict) else set()
        gaps = sorted(label_keys - nav_keys)
        if gaps:
            missing[messages_file.name] = gaps
    return missing


def covered(route: str, nav_routes: set[str]) -> bool:
    if route in nav_routes:
        return True
    return any(parent != "/" and route.startswith(parent + "/") for parent in nav_routes)


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--root", default=".", help="Repository root")
    args = parser.parse_args()

    root = Path(args.root).resolve()
    routes = locale_routes(root)
    nav_routes = navigation_routes(root)
    label_keys = navigation_label_keys(root)
    missing = sorted(route for route in routes if not covered(route, nav_routes))
    missing_labels = missing_nav_labels(root, label_keys)

    sidebar = (root / "apps/web/src/components/layout/sidebar.tsx").read_text(
        encoding="utf-8"
    )
    hidden_secondary_filter = "surface !== 'secondary'" in sidebar

    if missing or missing_labels or hidden_secondary_filter:
        if missing:
            print("NAVIGATION_COVERAGE_GUARD_MISSING_ROUTES")
            for route in missing:
                print(f"- {route}")
        if missing_labels:
            print("NAVIGATION_COVERAGE_GUARD_MISSING_LABEL_KEYS")
            for file_name, gaps in missing_labels.items():
                print(f"- {file_name}: {', '.join(gaps)}")
        if hidden_secondary_filter:
            print("NAVIGATION_COVERAGE_GUARD_HIDDEN_SECONDARY_ITEMS")
            print("- Sidebar must not filter product nav items by surface !== 'secondary'.")
        return 1

    print(
        "AWOOOI_NAVIGATION_COVERAGE_GUARD_OK "
        f"routes={len(routes)} nav_routes={len(nav_routes)} nav_label_keys={len(label_keys)}"
    )
    return 0


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