#!/usr/bin/env python3
"""Generate CRD/resource catalog metadata from upstream Omni resources."""

from __future__ import annotations

import pprint
import re
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
RESOURCES_ROOT = ROOT / "refs/libs/omni/client/pkg/omni/resources"
RESOURCES_CONST_FILE = RESOURCES_ROOT / "resources.go"
OUT = ROOT / "src/omni/generated/crd_catalog.py"

TYPE_RE = re.compile(
    r'^\s*(?:const\s+)?(?P<const>[A-Za-z0-9_]+Type)\s*=\s*resource\.Type\("(?P<rtype>[^"]+)"\)\s*$'
)
DEFAULT_NAMESPACE_RE = re.compile(r"DefaultNamespace:\s*resources\.([A-Za-z0-9_]+)")
NEW_METADATA_NAMESPACE_RE = re.compile(r"resource\.NewMetadata\(\s*resources\.([A-Za-z0-9_]+),")
PRINT_COLUMN_RE = re.compile(r'Name:\s*"([^"]+)"')
NAMESPACE_CONST_RE = re.compile(r'const\s+([A-Za-z0-9_]+)\s+resource\.Namespace\s*=\s*"([^"]+)"')


def _namespace_constants() -> dict[str, str]:
    if not RESOURCES_CONST_FILE.exists():
        return {}
    content = RESOURCES_CONST_FILE.read_text(encoding="utf-8")
    constants = dict(NAMESPACE_CONST_RE.findall(content))
    if "InfraProviderEphemeralNamespace" not in constants:
        base = constants.get("InfraProviderNamespace")
        if base:
            constants["InfraProviderEphemeralNamespace"] = f"{base}-ephemeral"
    return constants


NAMESPACE_CONSTANTS = _namespace_constants()


def _collect_comment(lines: list[str], idx: int) -> str:
    out: list[str] = []
    i = idx - 1
    while i >= 0:
        raw = lines[i].strip()
        if not raw:
            break
        if not raw.startswith("//"):
            break
        text = raw[2:].strip()
        if text and not text.startswith("This Source Code Form is subject"):
            out.append(text)
        i -= 1
    out.reverse()
    return " ".join(out).strip()


def _default_namespace(content: str) -> str | None:
    match = DEFAULT_NAMESPACE_RE.search(content)
    if match:
        return NAMESPACE_CONSTANTS.get(match.group(1), match.group(1))
    match = NEW_METADATA_NAMESPACE_RE.search(content)
    if match:
        return NAMESPACE_CONSTANTS.get(match.group(1), match.group(1))
    return None


def _normalize_alias(token: str) -> str:
    normalized = token.strip().lower().replace("_", "").replace("-", "")
    return normalized


def _aliases(const_name: str, resource_type: str) -> list[str]:
    aliases: set[str] = set()
    base = resource_type.split(".", 1)[0]
    aliases.add(_normalize_alias(base))
    if base.endswith("es"):
        aliases.add(_normalize_alias(base[:-2]))
    elif base.endswith("s"):
        aliases.add(_normalize_alias(base[:-1]))
    aliases.add(_normalize_alias(const_name.replace("Type", "")))
    aliases.add(_normalize_alias(resource_type))
    return sorted(alias for alias in aliases if alias)


def build_catalog() -> dict[str, dict[str, object]]:
    catalog: dict[str, dict[str, object]] = {}
    for path in sorted(RESOURCES_ROOT.rglob("*.go")):
        content = path.read_text(encoding="utf-8")
        lines = content.splitlines()
        namespace = _default_namespace(content)
        columns = sorted(set(PRINT_COLUMN_RE.findall(content)))

        for idx, line in enumerate(lines):
            match = TYPE_RE.match(line)
            if not match:
                continue

            const_name = match.group("const")
            resource_type = match.group("rtype")
            comment = _collect_comment(lines, idx)
            description = comment or f"Omni resource type `{resource_type}`."
            catalog[resource_type] = {
                "type": resource_type,
                "const_name": const_name,
                "description": description,
                "default_namespace": namespace,
                "print_columns": columns,
                "aliases": _aliases(const_name, resource_type),
                "source_file": str(path.relative_to(ROOT)),
            }
    return dict(sorted(catalog.items(), key=lambda item: item[0]))


def render(catalog: dict[str, dict[str, object]]) -> str:
    payload = pprint.pformat(catalog, width=120, sort_dicts=True)
    lines = [
        '"""Generated CRD/resource catalog.',
        "",
        "This file is generated by scripts/generate_crd_catalog.py.",
        '"""',
        "",
        "from __future__ import annotations",
        "",
        f"CRD_CATALOG = {payload}",
        "",
    ]
    return "\n".join(lines)


def main() -> None:
    OUT.parent.mkdir(parents=True, exist_ok=True)
    catalog = build_catalog()
    OUT.write_text(render(catalog), encoding="utf-8")
    print(f"wrote {OUT}")


if __name__ == "__main__":
    main()
