"""Step definitions for devcontainer_sandbox_strategy.feature.

Tests that devcontainer-instance uses snapshot sandbox strategy,
has the correct child types, and that ContainerLifecycleState uses
'discovered' as the initial state.
"""

from __future__ import annotations

from behave import then, when
from behave.runner import Context

from cleveragents.application.services._resource_registry_data import (
    BUILTIN_TYPES,
)
from cleveragents.domain.models.core.container_lifecycle import (
    ContainerLifecycleTracker,
)
from cleveragents.resource.handlers.devcontainer import DevcontainerHandler

# ── When steps ───────────────────────────────────────────────


@when("I inspect DevcontainerHandler class attributes")
def step_inspect_devcontainer_handler(context: Context) -> None:
    """Capture DevcontainerHandler class attributes for inspection."""
    context.devcontainer_handler_strategy = DevcontainerHandler._default_strategy


@when('I create a new ContainerLifecycleTracker for resource "{resource_id}"')
def step_create_tracker_for_sandbox(context: Context, resource_id: str) -> None:
    """Create a new ContainerLifecycleTracker with default state."""
    context.sandbox_tracker = ContainerLifecycleTracker(resource_id=resource_id)


@when('I look up "{type_name}" in BUILTIN_TYPES')
def step_look_up_in_builtin_types(context: Context, type_name: str) -> None:
    """Look up a resource type entry in BUILTIN_TYPES."""
    context.builtin_type_entry = None
    for entry in BUILTIN_TYPES:
        if entry.get("name") == type_name:
            context.builtin_type_entry = entry
            break


# ── Then steps ───────────────────────────────────────────────


@then('the DevcontainerHandler _default_strategy should be "{expected}"')
def step_devcontainer_handler_strategy(context: Context, expected: str) -> None:
    strategy = context.devcontainer_handler_strategy
    strategy_value = strategy.value if hasattr(strategy, "value") else str(strategy)
    assert strategy_value == expected, (
        f"Expected DevcontainerHandler._default_strategy to be '{expected}', "
        f"got '{strategy_value}'"
    )


@then('the spec sandbox_strategy should be "{expected}"')
def step_spec_sandbox_strategy(context: Context, expected: str) -> None:
    spec = context.resource_type_spec
    assert spec is not None, "No resource type spec found"
    actual = spec.get("sandbox_strategy")
    assert actual == expected, f"Expected sandbox_strategy '{expected}', got '{actual}'"


@then('the spec child_types should contain "{child_type}"')
def step_spec_child_types_contains(context: Context, child_type: str) -> None:
    spec = context.resource_type_spec
    assert spec is not None, "No resource type spec found"
    child_types: list[str] = spec.get("child_types", [])
    assert child_type in child_types, (
        f"Expected '{child_type}' in child_types {child_types}"
    )


@then('the tracker initial state should be "{expected}"')
def step_tracker_initial_state(context: Context, expected: str) -> None:
    tracker = context.sandbox_tracker
    actual = tracker.current_state.value
    assert actual == expected, (
        f"Expected initial tracker state '{expected}', got '{actual}'"
    )


@then('the lifecycle enum values should contain "{expected}"')
def step_lifecycle_enum_contains(context: Context, expected: str) -> None:
    values = context.enum_values
    assert expected in values, (
        f"Expected '{expected}' in lifecycle enum values {values}"
    )


@then('the lifecycle enum values should not contain "{unexpected}"')
def step_lifecycle_enum_not_contains(context: Context, unexpected: str) -> None:
    values = context.enum_values
    assert unexpected not in values, (
        f"Expected '{unexpected}' NOT to be in lifecycle enum values {values}"
    )


@then('the BUILTIN_TYPES entry sandbox_strategy should be "{expected}"')
def step_builtin_types_sandbox_strategy(context: Context, expected: str) -> None:
    entry = context.builtin_type_entry
    assert entry is not None, "No BUILTIN_TYPES entry found"
    actual = entry.get("sandbox_strategy")
    assert actual == expected, (
        f"Expected BUILTIN_TYPES sandbox_strategy '{expected}', got '{actual}'"
    )


@then('the BUILTIN_TYPES entry child_types should include "{child_type}"')
def step_builtin_types_child_types(context: Context, child_type: str) -> None:
    entry = context.builtin_type_entry
    assert entry is not None, "No BUILTIN_TYPES entry found"
    child_types: list[str] = entry.get("child_types", [])
    assert child_type in child_types, (
        f"Expected '{child_type}' in BUILTIN_TYPES child_types {child_types}"
    )
