"""Robot Framework helper for skill context and registry smoke tests.

Provides a CLI-style interface for Robot to invoke context creation,
resource resolution, change tracking, write guard, and registry operations.
Exit code 0 = success, 1 = failure.

Usage:
    python robot/helper_skill_context.py create-context
    python robot/helper_skill_context.py resolve-resource
    python robot/helper_skill_context.py track-invocation
    python robot/helper_skill_context.py write-guard
    python robot/helper_skill_context.py registry-crud
    python robot/helper_skill_context.py registry-list
    python robot/helper_skill_context.py registry-resolve
"""

from __future__ import annotations

import sys
from pathlib import Path
from typing import Any

# Ensure the src directory is on the import path.
_SRC = str(Path(__file__).resolve().parents[1] / "src")
if _SRC not in sys.path:
    sys.path.insert(0, _SRC)

from cleveragents.domain.models.core.skill import (  # noqa: E402
    Skill,
    SkillResolver,
)
from cleveragents.skills.context import SkillContext, SkillExecutionError  # noqa: E402
from cleveragents.skills.protocol import (  # noqa: E402
    SkillDefinition,
    SkillMetadata,
)
from cleveragents.skills.registry import SkillRegistry  # noqa: E402


def _make_defn(name: str, **kw: Any) -> SkillDefinition:
    """Create a SkillDefinition with defaults."""
    skill = Skill(name=name, description=f"Test {name}", **kw)
    resolver = SkillResolver()
    resolved = resolver.resolve_tools(skill, {})
    meta = SkillMetadata.from_skill(skill, resolved=resolved)
    return SkillDefinition(skill=skill, resolved_tools=resolved, metadata=meta)


def _cmd_create_context() -> int:
    """Test SkillContext creation."""
    ctx = SkillContext(
        plan_id="plan-robot",
        project_id="proj-robot",
        sandbox_path=Path("/tmp/robot-sandbox"),
    )
    if ctx.plan_id != "plan-robot":
        print(f"skill-context-fail: unexpected plan_id {ctx.plan_id}")
        return 1
    if ctx.is_read_only():
        print("skill-context-fail: should not be read-only")
        return 1
    print(f"skill-context-ok: plan={ctx.plan_id}")
    return 0


def _cmd_resolve_resource() -> int:
    """Test resource resolution."""
    ctx = SkillContext(
        plan_id="plan-res",
        project_id="proj-res",
        sandbox_path=Path("/tmp/res-sandbox"),
        resource_bindings={"git-checkout": "/repo/path"},
    )
    result = ctx.resolve_resource("git-checkout")
    if result != "/repo/path":
        print(f"skill-context-fail: unexpected resource {result}")
        return 1
    print(f"skill-context-resolve-ok: {result}")
    return 0


def _cmd_track_invocation() -> int:
    """Test change tracking."""
    ctx = SkillContext(
        plan_id="plan-track",
        project_id="proj-track",
        sandbox_path=Path("/tmp/track-sandbox"),
    )
    ctx.register_tool_invocation("local/test-tool", {"a": 1}, {"b": 2}, 15.5)
    if len(ctx.change_tracker) != 1:
        print(f"skill-context-fail: expected 1 record, got {len(ctx.change_tracker)}")
        return 1
    if ctx.change_tracker[0]["tool_name"] != "local/test-tool":
        print("skill-context-fail: wrong tool_name in tracker")
        return 1
    print("skill-context-track-ok")
    return 0


def _cmd_write_guard() -> int:
    """Test write guard enforcement."""
    ctx = SkillContext(
        plan_id="plan-guard",
        project_id="proj-guard",
        sandbox_path=Path("/tmp/guard-sandbox"),
        read_only=True,
    )
    try:
        ctx.enforce_write_guard("local/write-tool")
        print("skill-context-fail: expected SkillError")
        return 1
    except SkillExecutionError as e:
        if e.error_type.value != "permission_denied":
            print(f"skill-context-fail: unexpected error type {e.error_type}")
            return 1
    print("skill-context-guard-ok")
    return 0


def _cmd_registry_crud() -> int:
    """Test registry register/get/unregister."""
    reg = SkillRegistry()
    defn = _make_defn("local/robot-reg")
    reg.register(defn)
    got = reg.get("local/robot-reg")
    if got.skill.name != "local/robot-reg":
        print(f"skill-registry-fail: unexpected name {got.skill.name}")
        return 1
    reg.unregister("local/robot-reg")
    try:
        reg.get("local/robot-reg")
        print("skill-registry-fail: expected not-found error")
        return 1
    except SkillExecutionError:
        pass
    print("skill-registry-crud-ok")
    return 0


def _cmd_registry_list() -> int:
    """Test registry list_all."""
    reg = SkillRegistry()
    reg.register(_make_defn("local/list-a"))
    reg.register(_make_defn("local/list-b"))
    items = reg.list_all()
    if len(items) != 2:
        print(f"skill-registry-fail: expected 2, got {len(items)}")
        return 1
    print(f"skill-registry-list-ok: {len(items)} skills")
    return 0


def _cmd_registry_resolve() -> int:
    """Test registry tool resolution."""
    reg = SkillRegistry()
    defn = _make_defn("local/resolve-skill", tool_refs=["local/tool-x"])
    reg.register(defn)
    tools = reg.resolve_tools("local/resolve-skill")
    if len(tools) != 1:
        print(f"skill-registry-fail: expected 1 tool, got {len(tools)}")
        return 1
    print(f"skill-registry-resolve-ok: {len(tools)} tools")
    return 0


_COMMANDS = {
    "create-context": _cmd_create_context,
    "resolve-resource": _cmd_resolve_resource,
    "track-invocation": _cmd_track_invocation,
    "write-guard": _cmd_write_guard,
    "registry-crud": _cmd_registry_crud,
    "registry-list": _cmd_registry_list,
    "registry-resolve": _cmd_registry_resolve,
}


def main() -> int:
    """Entry point called by Robot Framework ``Run Process``."""
    if len(sys.argv) < 2:
        print(
            "Usage: helper_skill_context.py "
            "<create-context|resolve-resource|track-invocation|write-guard"
            "|registry-crud|registry-list|registry-resolve>"
        )
        return 1

    command = sys.argv[1]
    handler = _COMMANDS.get(command)
    if handler is None:
        print(f"Unknown command: {command}")
        return 1

    return handler()


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