"""Robot Framework helper for resource type inheritance tests.

Each public function is exposed as a Robot keyword.  When run standalone
via ``python robot/helper_resource_type_inheritance.py <subcommand>``
each command prints ``<subcommand>-ok`` on success.
"""

from __future__ import annotations

import sys
from typing import Any

from cleveragents.resource.inheritance import (
    MAX_CHAIN_DEPTH,
    ResourceTypeCircularInheritanceError,
    ResourceTypeInheritanceDepthError,
    find_subtypes,
    is_subtype_of,
    resolve_fields,
    resolve_inheritance_chain,
    validate_chain,
)

# ---------------------------------------------------------------------------
# Shared test registries
# ---------------------------------------------------------------------------

_SIMPLE_REGISTRY: dict[str, Any] = {
    "resource": {},
    "container-instance": {"inherits": "resource", "sandbox_strategy": "docker"},
    "devcontainer-instance": {
        "inherits": "container-instance",
        "sandbox_strategy": "devcontainer",
        "cli_args": [{"name": "profile", "type": "string"}],
    },
}

_DEEP_REGISTRY: dict[str, Any] = {
    "root": {},
    "level-1": {"inherits": "root"},
    "level-2": {"inherits": "level-1"},
    "level-3": {"inherits": "level-2"},
    "level-4": {"inherits": "level-3"},
}

_FIELD_REGISTRY: dict[str, Any] = {
    "base": {
        "sandbox_strategy": "copy_on_write",
        "resource_kind": "physical",
        "cli_args": [{"name": "path", "type": "string"}],
        "child_types": ["alpha"],
    },
    "mid": {
        "inherits": "base",
        "resource_kind": "virtual",
        "cli_args": [{"name": "tag", "type": "string"}],
        "child_types": ["beta"],
    },
    "leaf": {
        "inherits": "mid",
        "sandbox_strategy": "none",
        "cli_args": [
            {"name": "path", "type": "int"},  # overrides base's "path"
        ],
    },
}

_WIDE_REGISTRY: dict[str, Any] = {
    "ancestor": {},
}
for _i in range(20):
    _WIDE_REGISTRY[f"child-{_i}"] = {"inherits": "ancestor"}


# ---------------------------------------------------------------------------
# Robot keywords
# ---------------------------------------------------------------------------


def resolve_inheritance_chain_keyword(
    type_name: str,
) -> list[str]:
    """Resolve an inheritance chain using the simple registry."""
    return resolve_inheritance_chain(type_name, _SIMPLE_REGISTRY)


def resolve_deep_chain(type_name: str) -> list[str]:
    """Resolve an inheritance chain using the deep (4-level) registry."""
    return resolve_inheritance_chain(type_name, _DEEP_REGISTRY)


def check_is_subtype_of(
    type_name: str,
    ancestor_name: str,
) -> bool:
    """Return True if *type_name* is a subtype of *ancestor_name*."""
    return is_subtype_of(type_name, ancestor_name, _SIMPLE_REGISTRY)


def check_is_subtype_deep(
    type_name: str,
    ancestor_name: str,
) -> bool:
    """Return True if *type_name* is a subtype of *ancestor_name* (deep)."""
    return is_subtype_of(type_name, ancestor_name, _DEEP_REGISTRY)


def resolve_merged_fields(type_name: str) -> dict[str, Any]:
    """Resolve merged fields for *type_name* using the field registry."""
    return resolve_fields(type_name, _FIELD_REGISTRY)


def find_all_subtypes(ancestor_name: str) -> list[str]:
    """Find all subtypes of *ancestor_name* in the wide registry."""
    return find_subtypes(ancestor_name, _WIDE_REGISTRY)


def validate_chain_keyword(
    type_name: str,
    inherits: str | None,
) -> list[str]:
    """Validate a chain declaration against the simple registry."""
    return validate_chain(type_name, inherits, _SIMPLE_REGISTRY)


def get_max_chain_depth() -> int:
    """Return the configured MAX_CHAIN_DEPTH constant."""
    return MAX_CHAIN_DEPTH


def detect_circular_inheritance() -> str:
    """Attempt to resolve a circular chain; return error class name."""
    circular: dict[str, Any] = {
        "a": {"inherits": "b"},
        "b": {"inherits": "a"},
    }
    try:
        resolve_inheritance_chain("a", circular)
        return "no-error"
    except ResourceTypeCircularInheritanceError:
        return "ResourceTypeCircularInheritanceError"


def detect_depth_exceeded() -> str:
    """Attempt to resolve an overly-deep chain; return error class name."""
    deep: dict[str, Any] = {"t0": {}}
    for i in range(1, MAX_CHAIN_DEPTH + 2):
        deep[f"t{i}"] = {"inherits": f"t{i - 1}"}
    leaf = f"t{MAX_CHAIN_DEPTH + 1}"
    try:
        resolve_inheritance_chain(leaf, deep)
        return "no-error"
    except ResourceTypeInheritanceDepthError:
        return "ResourceTypeInheritanceDepthError"


# ---------------------------------------------------------------------------
# Standalone CLI
# ---------------------------------------------------------------------------


def _chain_resolve() -> None:
    chain = resolve_inheritance_chain("devcontainer-instance", _SIMPLE_REGISTRY)
    assert chain == ["devcontainer-instance", "container-instance", "resource"], (
        f"unexpected chain: {chain}"
    )
    print("chain-resolve-ok")


def _subtype_check() -> None:
    assert is_subtype_of("devcontainer-instance", "resource", _SIMPLE_REGISTRY)
    assert not is_subtype_of("resource", "devcontainer-instance", _SIMPLE_REGISTRY)
    print("subtype-check-ok")


def _field_merge() -> None:
    fields = resolve_fields("leaf", _FIELD_REGISTRY)
    assert fields["sandbox_strategy"] == "none", f"got {fields['sandbox_strategy']}"
    assert fields["resource_kind"] == "virtual", f"got {fields['resource_kind']}"
    # cli_args: "path" from leaf overrides base, "tag" from mid kept
    names = [a["name"] for a in fields["cli_args"]]
    assert "tag" in names, f"tag missing from {names}"
    assert "path" in names, f"path missing from {names}"
    print("field-merge-ok")


def _find_subtypes_cmd() -> None:
    subtypes = find_subtypes("ancestor", _WIDE_REGISTRY)
    assert len(subtypes) == 20, f"expected 20 subtypes, got {len(subtypes)}"
    print("find-subtypes-ok")


def _circular_detect() -> None:
    result = detect_circular_inheritance()
    assert result == "ResourceTypeCircularInheritanceError", f"got {result}"
    print("circular-detect-ok")


_COMMANDS = {
    "chain-resolve": _chain_resolve,
    "subtype-check": _subtype_check,
    "field-merge": _field_merge,
    "find-subtypes": _find_subtypes_cmd,
    "circular-detect": _circular_detect,
}


if __name__ == "__main__":
    if len(sys.argv) < 2 or sys.argv[1] not in _COMMANDS:
        print(f"Usage: {sys.argv[0]} <{'|'.join(_COMMANDS)}>", file=sys.stderr)
        sys.exit(1)
    _COMMANDS[sys.argv[1]]()
