"""Step definitions for AWS sandbox lifecycle scenarios.

Tests CloudSandboxStrategy.create/commit/rollback with mocked boto3.
"""

from __future__ import annotations

from typing import Any
from unittest.mock import patch

from behave import given, when  # type: ignore[attr-defined]

from cleveragents.resource.handlers.cloud_aws import CloudSandboxStrategy


@given('awssdk a cloud sandbox strategy for "{provider}"')
def step_sandbox_strategy(context: Any, provider: str) -> None:
    """Create a CloudSandboxStrategy for the given provider."""
    context.cloud_sandbox = CloudSandboxStrategy(provider)  # type: ignore[attr-defined]


@when('awssdk I call create on the AWS sandbox strategy with plan "{plan_id}"')
def step_sandbox_create_aws(context: Any, plan_id: str) -> None:
    """Call create on the CloudSandboxStrategy."""
    strategy: CloudSandboxStrategy = context.cloud_sandbox  # type: ignore[attr-defined]
    context.raised_error = None  # type: ignore[attr-defined]
    context.raised_error_type = None  # type: ignore[attr-defined]

    boto3_avail = getattr(context, "boto3_available", True)
    with patch(
        "cleveragents.resource.handlers.cloud_aws._BOTO3_AVAILABLE", boto3_avail
    ):
        try:
            strategy.create("res-test-001", plan_id)
        except (NotImplementedError, ImportError, ValueError) as exc:
            context.raised_error = exc  # type: ignore[attr-defined]
            context.raised_error_type = type(exc).__name__  # type: ignore[attr-defined]


@when('awssdk I call commit on the AWS sandbox strategy with plan "{plan_id}"')
def step_sandbox_commit_aws(context: Any, plan_id: str) -> None:
    """Call commit on the CloudSandboxStrategy."""
    strategy: CloudSandboxStrategy = context.cloud_sandbox  # type: ignore[attr-defined]
    context.raised_error = None  # type: ignore[attr-defined]
    context.raised_error_type = None  # type: ignore[attr-defined]

    boto3_avail = getattr(context, "boto3_available", True)
    with patch(
        "cleveragents.resource.handlers.cloud_aws._BOTO3_AVAILABLE", boto3_avail
    ):
        try:
            strategy.commit("res-test-001", plan_id)
        except (NotImplementedError, ImportError, ValueError) as exc:
            context.raised_error = exc  # type: ignore[attr-defined]
            context.raised_error_type = type(exc).__name__  # type: ignore[attr-defined]


@when('awssdk I call rollback on the AWS sandbox strategy with plan "{plan_id}"')
def step_sandbox_rollback_aws(context: Any, plan_id: str) -> None:
    """Call rollback on the CloudSandboxStrategy."""
    strategy: CloudSandboxStrategy = context.cloud_sandbox  # type: ignore[attr-defined]
    context.raised_error = None  # type: ignore[attr-defined]
    context.raised_error_type = None  # type: ignore[attr-defined]

    boto3_avail = getattr(context, "boto3_available", True)
    with patch(
        "cleveragents.resource.handlers.cloud_aws._BOTO3_AVAILABLE", boto3_avail
    ):
        try:
            strategy.rollback("res-test-001", plan_id)
        except (NotImplementedError, ImportError, ValueError) as exc:
            context.raised_error = exc  # type: ignore[attr-defined]
            context.raised_error_type = type(exc).__name__  # type: ignore[attr-defined]


# behave's parse format {plan_id} uses .+? and won't match an empty string,
# so we need explicit overloads for the empty plan_id scenarios.


@when('awssdk I call create on the AWS sandbox strategy with plan ""')
def step_sandbox_create_aws_empty(context: Any) -> None:
    """Call create on the CloudSandboxStrategy with empty plan_id."""
    step_sandbox_create_aws(context, "")


@when('awssdk I call commit on the AWS sandbox strategy with plan ""')
def step_sandbox_commit_aws_empty(context: Any) -> None:
    """Call commit on the CloudSandboxStrategy with empty plan_id."""
    step_sandbox_commit_aws(context, "")


@when('awssdk I call rollback on the AWS sandbox strategy with plan ""')
def step_sandbox_rollback_aws_empty(context: Any) -> None:
    """Call rollback on the CloudSandboxStrategy with empty plan_id."""
    step_sandbox_rollback_aws(context, "")
