"""Platform availability matrix for Tukuy transformers.

Answers: "does transformer X work in Python, JS, or both?"

The JS registry is generated by ``js/build.js`` and written to
``tukuy/js-registry.json``.  The Python registry comes from the
plugin system at runtime.

Usage::

    from tukuy.platforms import get_platform_matrix, get_platforms

    # Single lookup
    platforms = get_platforms("slugify")  # {"python", "js"}

    # Full matrix
    matrix = get_platform_matrix()
    # {"slugify": {"python", "js"}, "file_read": {"python"}, ...}
"""

from __future__ import annotations

import json
from functools import lru_cache
from pathlib import Path
from typing import Dict, FrozenSet, List, Optional, Set


_JS_REGISTRY_PATH = Path(__file__).parent / "js-registry.json"


@lru_cache(maxsize=1)
def _load_js_registry() -> Dict:
    """Load the JS transformer registry manifest."""
    if not _JS_REGISTRY_PATH.exists():
        return {"transformers": [], "categories": {}}
    with open(_JS_REGISTRY_PATH, "r", encoding="utf-8") as f:
        return json.load(f)


def get_js_transformer_names() -> Set[str]:
    """Return the set of transformer names available in JS."""
    registry = _load_js_registry()
    return {t["name"] for t in registry.get("transformers", [])}


def get_js_categories() -> Dict[str, List[str]]:
    """Return JS transformer names grouped by category."""
    return _load_js_registry().get("categories", {})


def get_js_transformer_metadata(name: str) -> Optional[Dict]:
    """Return full JS metadata for a transformer, or None."""
    for t in _load_js_registry().get("transformers", []):
        if t["name"] == name:
            return t
    return None


def get_python_transformer_names() -> Set[str]:
    """Return the set of transformer names available in Python."""
    try:
        from .registry import get_shared_registry
        reg = get_shared_registry()
        return set(reg.transformers.keys())
    except Exception:
        return set()


def get_platforms(name: str) -> FrozenSet[str]:
    """Get the set of platforms a transformer is available on.

    Returns:
        frozenset of ``"python"``, ``"js"``, or both.
        Empty frozenset if the name is unknown.
    """
    platforms: Set[str] = set()
    if name in get_js_transformer_names():
        platforms.add("js")
    if name in get_python_transformer_names():
        platforms.add("python")
    return frozenset(platforms)


def get_platform_matrix() -> Dict[str, FrozenSet[str]]:
    """Build the full platform matrix for all known transformers.

    Returns:
        Dict mapping transformer name to frozenset of platforms.
    """
    all_names = get_js_transformer_names() | get_python_transformer_names()
    js_names = get_js_transformer_names()
    py_names = get_python_transformer_names()

    matrix: Dict[str, FrozenSet[str]] = {}
    for name in sorted(all_names):
        platforms: Set[str] = set()
        if name in js_names:
            platforms.add("js")
        if name in py_names:
            platforms.add("python")
        matrix[name] = frozenset(platforms)
    return matrix


def get_platform_summary() -> Dict[str, List[str]]:
    """Summarize transformers by platform availability.

    Returns:
        Dict with keys ``"python_only"``, ``"js_only"``, ``"both"``.
    """
    matrix = get_platform_matrix()
    summary: Dict[str, List[str]] = {
        "python_only": [],
        "js_only": [],
        "both": [],
    }
    for name, platforms in matrix.items():
        if platforms == frozenset({"python", "js"}):
            summary["both"].append(name)
        elif platforms == frozenset({"python"}):
            summary["python_only"].append(name)
        elif platforms == frozenset({"js"}):
            summary["js_only"].append(name)
    return summary


__all__ = [
    "get_platforms",
    "get_platform_matrix",
    "get_platform_summary",
    "get_js_transformer_names",
    "get_js_categories",
    "get_js_transformer_metadata",
    "get_python_transformer_names",
]
