"""Helper utilities for resource handler Robot smoke tests.

Each command prints a single ``<command>-ok`` token on success so the
calling Robot test can assert on ``stdout``.
"""

from __future__ import annotations

import sys
from datetime import datetime
from unittest.mock import MagicMock, PropertyMock

from cleveragents.domain.models.core.resource import (
    PhysVirt,
    Resource,
    ResourceCapabilities,
)
from cleveragents.infrastructure.sandbox.factory import SandboxFactory
from cleveragents.infrastructure.sandbox.manager import SandboxManager
from cleveragents.infrastructure.sandbox.protocol import (
    SandboxContext,
    SandboxStatus,
)
from cleveragents.resource.handlers.fs_directory import FsDirectoryHandler
from cleveragents.resource.handlers.git_checkout import GitCheckoutHandler
from cleveragents.resource.handlers.protocol import ResourceHandler
from cleveragents.resource.handlers.resolver import (
    HandlerResolutionError,
    clear_handler_cache,
    resolve_handler,
)
from cleveragents.tool.context import BoundResource


def _make_resource(rtype: str, location: str) -> Resource:
    """Create a test resource with a valid ULID."""
    return Resource(
        resource_id="01KJ5C5TPMP8GGX3QC83E2MAQS",
        resource_type_name=rtype,
        classification=PhysVirt.PHYSICAL,
        location=location,
        capabilities=ResourceCapabilities(
            readable=True, writable=True, sandboxable=True
        ),
    )


def _make_mock_manager() -> SandboxManager:
    """Create a SandboxManager with a mock factory."""
    mock_factory = MagicMock(spec=SandboxFactory)
    mock_sandbox = MagicMock()
    mock_sandbox.sandbox_id = "sb-robot-001"
    type(mock_sandbox).status = PropertyMock(return_value=SandboxStatus.CREATED)
    mock_sandbox.context = SandboxContext(
        sandbox_id="sb-robot-001",
        sandbox_path="/tmp/sandbox/sb-robot-001",
        original_path="/tmp/original",
        resource_id="res-robot",
        plan_id="plan-robot",
        created_at=datetime.now(),
    )
    mock_sandbox.create.return_value = mock_sandbox.context
    mock_factory.create_sandbox.return_value = mock_sandbox
    return SandboxManager(factory=mock_factory, cleanup_on_exit=False)


def _protocol_check() -> None:
    """Verify both handlers satisfy the ResourceHandler protocol."""
    git = GitCheckoutHandler()
    fs = FsDirectoryHandler()
    assert isinstance(git, ResourceHandler), "GitCheckoutHandler not a ResourceHandler"
    assert isinstance(fs, ResourceHandler), "FsDirectoryHandler not a ResourceHandler"
    print("protocol-check-ok")


def _git_resolve() -> None:
    """Verify GitCheckoutHandler resolves a resource."""
    resource = _make_resource("git-checkout", "/tmp/test-repo")
    manager = _make_mock_manager()
    handler = GitCheckoutHandler()
    bound = handler.resolve(
        resource=resource,
        plan_id="PLAN_ROBOT",
        slot_name="repo",
        sandbox_manager=manager,
    )
    assert isinstance(bound, BoundResource)
    assert bound.sandbox_path, "sandbox_path empty"
    assert bound.resource_type == "git-checkout"
    print("git-resolve-ok")


def _fs_resolve() -> None:
    """Verify FsDirectoryHandler resolves a resource."""
    resource = _make_resource("fs-directory", "/tmp/test-dir")
    manager = _make_mock_manager()
    handler = FsDirectoryHandler()
    bound = handler.resolve(
        resource=resource,
        plan_id="PLAN_ROBOT",
        slot_name="workdir",
        sandbox_manager=manager,
    )
    assert isinstance(bound, BoundResource)
    assert bound.sandbox_path, "sandbox_path empty"
    assert bound.resource_type == "fs-directory"
    print("fs-resolve-ok")


def _resolver_import() -> None:
    """Verify handler resolver loads handlers from module:class strings."""
    clear_handler_cache()
    git = resolve_handler(
        "cleveragents.resource.handlers.git_checkout:GitCheckoutHandler"
    )
    assert isinstance(git, GitCheckoutHandler)
    fs = resolve_handler(
        "cleveragents.resource.handlers.fs_directory:FsDirectoryHandler"
    )
    assert isinstance(fs, FsDirectoryHandler)
    print("resolver-import-ok")


def _resolver_error() -> None:
    """Verify handler resolver raises on bad references."""
    clear_handler_cache()
    try:
        resolve_handler("nonexistent.module:FakeClass")
        print("resolver-error-FAIL")
    except HandlerResolutionError:
        print("resolver-error-ok")


_COMMANDS = {
    "protocol-check": _protocol_check,
    "git-resolve": _git_resolve,
    "fs-resolve": _fs_resolve,
    "resolver-import": _resolver_import,
    "resolver-error": _resolver_error,
}


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]]()
