"""Step definitions for cloud_handler_coverage_r3.feature.

Exercises the NotImplementedError stubs on CloudResourceHandler
for CRUD and lifecycle methods that are part of the ResourceHandler
protocol but intentionally unsupported for cloud resources.

Covered lines in src/cleveragents/resource/handlers/cloud.py:
  480  - read()
  484  - write()
  488  - delete()
  492  - list_children()
  496  - diff()
  500  - discover_children()
  512  - create_sandbox()
  523  - create_checkpoint()
  534  - rollback_to()
  545  - project_access()
"""

from unittest.mock import MagicMock

from behave import given, then, when

from cleveragents.domain.models.core.resource import (
    PhysVirt,
    Resource,
    ResourceCapabilities,
    SandboxStrategy,
)
from cleveragents.resource.handlers.cloud import CloudResourceHandler

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

_VALID_ULID = "01ARZ3NDEKTSV4RRFFQ69G5FAV"


def _make_resource(type_name: str = "aws-account") -> Resource:
    """Create a minimal Resource suitable for handler stub calls."""
    return Resource(
        resource_id=_VALID_ULID,
        resource_type_name=type_name,
        classification=PhysVirt.VIRTUAL,
        properties={},
        sandbox_strategy=SandboxStrategy.NONE,
        capabilities=ResourceCapabilities(),
    )


# ---------------------------------------------------------------------------
# Background
# ---------------------------------------------------------------------------


@given("clcov3 a CloudResourceHandler instance exists")
def step_create_handler(context):
    """Instantiate a CloudResourceHandler and store it on context."""
    context.clcov3_handler = CloudResourceHandler()


@given("clcov3 a dummy cloud resource exists")
def step_create_resource(context):
    """Create a minimal Resource for use in stub calls."""
    context.clcov3_resource = _make_resource()


# ---------------------------------------------------------------------------
# CRUD stubs - When steps
# ---------------------------------------------------------------------------


@when("clcov3 I call read on the handler")
def step_call_read(context):
    """Call handler.read() and capture the expected NotImplementedError."""
    context.clcov3_error = None
    try:
        context.clcov3_handler.read(resource=context.clcov3_resource, path="")
    except NotImplementedError as exc:
        context.clcov3_error = exc


@when("clcov3 I call write on the handler")
def step_call_write(context):
    """Call handler.write() and capture the expected NotImplementedError."""
    context.clcov3_error = None
    try:
        context.clcov3_handler.write(
            resource=context.clcov3_resource, path="/tmp/test", data=b"hello"
        )
    except NotImplementedError as exc:
        context.clcov3_error = exc


@when("clcov3 I call delete on the handler")
def step_call_delete(context):
    """Call handler.delete() and capture the expected NotImplementedError."""
    context.clcov3_error = None
    try:
        context.clcov3_handler.delete(resource=context.clcov3_resource, path="")
    except NotImplementedError as exc:
        context.clcov3_error = exc


@when("clcov3 I call list_children on the handler")
def step_call_list_children(context):
    """Call handler.list_children() and capture the expected NotImplementedError."""
    context.clcov3_error = None
    try:
        context.clcov3_handler.list_children(resource=context.clcov3_resource)
    except NotImplementedError as exc:
        context.clcov3_error = exc


@when("clcov3 I call diff on the handler")
def step_call_diff(context):
    """Call handler.diff() and capture the expected NotImplementedError."""
    context.clcov3_error = None
    try:
        context.clcov3_handler.diff(
            resource=context.clcov3_resource, other_location="/other/path"
        )
    except NotImplementedError as exc:
        context.clcov3_error = exc


@when("clcov3 I call discover_children on the handler")
def step_call_discover_children(context):
    """Call handler.discover_children() and capture the expected NotImplementedError."""
    context.clcov3_error = None
    try:
        context.clcov3_handler.discover_children(resource=context.clcov3_resource)
    except NotImplementedError as exc:
        context.clcov3_error = exc


# ---------------------------------------------------------------------------
# Lifecycle stubs - When steps
# ---------------------------------------------------------------------------


@when("clcov3 I call create_sandbox on the handler")
def step_call_create_sandbox(context):
    """Call handler.create_sandbox() and capture the expected NotImplementedError."""
    context.clcov3_error = None
    try:
        context.clcov3_handler.create_sandbox(
            resource=context.clcov3_resource,
            plan_id="plan-test-001",
            sandbox_manager=MagicMock(),
        )
    except NotImplementedError as exc:
        context.clcov3_error = exc


@when("clcov3 I call create_checkpoint on the handler")
def step_call_create_checkpoint(context):
    """Call handler.create_checkpoint() and capture the expected NotImplementedError."""
    context.clcov3_error = None
    try:
        context.clcov3_handler.create_checkpoint(
            resource=context.clcov3_resource,
            plan_id="plan-test-001",
            sandbox_manager=MagicMock(),
            phase="execution",
        )
    except NotImplementedError as exc:
        context.clcov3_error = exc


@when("clcov3 I call rollback_to on the handler")
def step_call_rollback_to(context):
    """Call handler.rollback_to() and capture the expected NotImplementedError."""
    context.clcov3_error = None
    try:
        context.clcov3_handler.rollback_to(
            resource=context.clcov3_resource,
            plan_id="plan-test-001",
            checkpoint_id="chk-001",
            sandbox_manager=MagicMock(),
        )
    except NotImplementedError as exc:
        context.clcov3_error = exc


@when("clcov3 I call project_access on the handler")
def step_call_project_access(context):
    """Call handler.project_access() and capture the expected NotImplementedError."""
    context.clcov3_error = None
    try:
        context.clcov3_handler.project_access(
            resource=context.clcov3_resource,
            principal="user@example.com",
            action="read",
            project_id="proj-001",
        )
    except NotImplementedError as exc:
        context.clcov3_error = exc


# ---------------------------------------------------------------------------
# Shared Then step
# ---------------------------------------------------------------------------


@then('clcov3 a NotImplementedError is stored with message "{method_name}"')
def step_verify_not_implemented(context, method_name):
    """Verify a NotImplementedError was captured and its message contains the method name."""
    assert context.clcov3_error is not None, (
        f"Expected NotImplementedError for {method_name}, but no exception was raised"
    )
    assert isinstance(context.clcov3_error, NotImplementedError), (
        f"Expected NotImplementedError, got {type(context.clcov3_error).__name__}"
    )
    msg = str(context.clcov3_error)
    assert method_name in msg, f"Expected '{method_name}' in error message, got: {msg}"
