"""Step definitions for exec_env_precedence.feature.

Self-contained step file for the 6-level execution environment
precedence chain.  All imports are top-level and guarded.
"""

from __future__ import annotations

from behave import then, when

from cleveragents.application.services.execution_environment_resolver import (
    ExecutionEnvironmentResolver,
)


def _resolver() -> ExecutionEnvironmentResolver:
    return ExecutionEnvironmentResolver()


# ── 6-Level Precedence Chain ─────────────────────────────


@when(
    'I resolve precedence with plan_env "{plan}" plan_priority "{pp}" '
    'project_env "{proj}" project_priority "{projp}" '
    "devcontainer {dc}"
)
def step_resolve_full(
    context: object,
    plan: str,
    pp: str,
    proj: str,
    projp: str,
    dc: str,
) -> None:
    context.prec_resolved = _resolver().resolve_with_precedence(
        plan_env=plan,
        plan_priority=pp,
        project_env=proj,
        project_priority=projp,
        devcontainer_available=dc.lower() == "true",
    )


@when(
    'I resolve precedence with tool_env "{tool}" plan_env "{plan}" '
    'plan_priority "{pp}" devcontainer {dc}'
)
def step_resolve_tool(
    context: object,
    tool: str,
    plan: str,
    pp: str,
    dc: str,
) -> None:
    context.prec_resolved = _resolver().resolve_with_precedence(
        tool_env=tool,
        plan_env=plan,
        plan_priority=pp,
        devcontainer_available=dc.lower() == "true",
    )


@when(
    'I resolve precedence with project_env "{proj}" '
    'project_priority "{projp}" devcontainer {dc}'
)
def step_resolve_proj(context: object, proj: str, projp: str, dc: str) -> None:
    context.prec_resolved = _resolver().resolve_with_precedence(
        project_env=proj,
        project_priority=projp,
        devcontainer_available=dc.lower() == "true",
    )


@when("I resolve precedence with devcontainer {dc}")
def step_resolve_default(context: object, dc: str) -> None:
    context.prec_resolved = _resolver().resolve_with_precedence(
        devcontainer_available=dc.lower() == "true",
    )


@when(
    'I resolve precedence with plan_env "{plan}" project_env "{proj}" devcontainer {dc}'
)
def step_resolve_both_fb(context: object, plan: str, proj: str, dc: str) -> None:
    context.prec_resolved = _resolver().resolve_with_precedence(
        plan_env=plan,
        project_env=proj,
        devcontainer_available=dc.lower() == "true",
    )


@then('the precedence resolved environment should be "{expected}"')
def step_check_resolved(context: object, expected: str) -> None:
    actual = context.prec_resolved.value
    assert actual == expected, f"Expected '{expected}', got '{actual}'"


# ── Devcontainer helpers ─────────────────────────────────


@when('I check has_devcontainer with types "{types}" for precedence')
def step_has_dc(context: object, types: str) -> None:
    type_list = [t.strip() for t in types.split(",")]
    context.prec_has_dc = _resolver().has_devcontainer(type_list)


@then("has_devcontainer should be {expected} for precedence")
def step_has_dc_check(context: object, expected: str) -> None:
    assert context.prec_has_dc == (expected.lower() == "true")


# ── ContextConfig priority field ─────────────────────────


@when('I create a ContextConfig with priority "{priority}" for precedence')
def step_ctx_config(context: object, priority: str) -> None:
    from cleveragents.domain.models.core.project import ContextConfig

    context.prec_ctx_config = ContextConfig(
        execution_environment="container",
        execution_env_priority=priority,
    )


@then('the context config priority should be "{priority}" for precedence')
def step_ctx_config_check(context: object, priority: str) -> None:
    assert context.prec_ctx_config.execution_env_priority == priority


# ── DAG walk ─────────────────────────────────────────────


@when('I resolve with DAG walk from "{rid}" with devcontainer ancestor for precedence')
def step_dag_with_dc(context: object, rid: str) -> None:
    context.prec_resolved = _resolver().resolve_with_dag(
        resource_id=rid,
        linked_resource_types={
            rid: "fs-file",
            "res-dir": "fs-directory",
            "res-dc": "devcontainer-instance",
        },
        parent_map={rid: ["res-dir"], "res-dir": ["res-dc"]},
    )


@when(
    'I resolve with DAG walk from "{rid}" without devcontainer ancestor for precedence'
)
def step_dag_no_dc(context: object, rid: str) -> None:
    context.prec_resolved = _resolver().resolve_with_dag(
        resource_id=rid,
        linked_resource_types={
            rid: "fs-file",
            "res-dir": "fs-directory",
            "res-checkout": "git-checkout",
        },
        parent_map={rid: ["res-dir"], "res-dir": ["res-checkout"]},
    )


# ── Container reference ──────────────────────────────────


@when('I parse container ref "{ref}" for precedence')
def step_parse_ref(context: object, ref: str) -> None:
    _, name = _resolver().parse_container_ref(ref)
    context.prec_ref_name = name


@then('the container ref name should be "{name}" for precedence')
def step_ref_name(context: object, name: str) -> None:
    assert context.prec_ref_name == name
