Feature: Devcontainer Session Cleanup and CLI Commands
  As a CleverAgents developer
  I want session-scoped container cleanup and CLI stop/rebuild commands
  So that containers are cleaned up when sessions end and can be managed via CLI

  # ── Session cleanup ────────────────────────────────────────

  Scenario: Active containers stopped on session cleanup
    Given a mock devcontainer CLI runner
    And an active container "01TESTLIFECYCLE0000000040" with container ID "ctr-a"
    And an active container "01TESTLIFECYCLE0000000041" with container ID "ctr-b"
    When I run session cleanup for session "session-001"
    Then the container state for "01TESTLIFECYCLE0000000040" should be "stopped"
    And the container state for "01TESTLIFECYCLE0000000041" should be "stopped"

  # ── Cleanup service integration ────────────────────────────

  Scenario: CleanupService stop_active_devcontainers is callable and returns list
    When I call CleanupService stop_active_devcontainers with no active containers
    Then the cleanup result should be an empty list
    And CleanupService should have a stop_active_devcontainers method

  Scenario: CleanupService stop_active_devcontainers calls handler cleanup
    When I call CleanupService stop_active_devcontainers with no active containers
    Then the cleanup result should be an empty list

  # ── stop_all_active_containers error path ──────────────────

  Scenario: Session cleanup handles stop failure gracefully
    Given a mock devcontainer CLI runner
    And the runner configured to raise exception on stop
    And an active container "01TESTLIFECYCLE0000000130" with container ID "ctr-fail"
    When I run session cleanup for session "session-err"
    Then the cleanup should return 0 stopped containers

  # ── CLI stop/rebuild commands (F6) ─────────────────────────

  Scenario: CLI stop succeeds for active devcontainer-instance
    Given a mock resource service with devcontainer "local/test-dc" id "01TESTLIFECYCLE0000000200" at "/workspace/project"
    And an active container "01TESTLIFECYCLE0000000200" with container ID "ctr-cli-stop"
    When I invoke CLI resource stop "local/test-dc"
    Then the CLI exit code should be 0
    And the CLI output should contain "Stopped"

  Scenario: CLI stop rejects non-devcontainer resource type
    Given a mock resource service with git-checkout "local/my-repo" id "01TESTLIFECYCLE0000000201"
    When I invoke CLI resource stop "local/my-repo"
    Then the devcontainer CLI exit code should be non-zero
    And the CLI output should contain "not a stoppable container type"

  Scenario: CLI rebuild succeeds for stopped devcontainer-instance
    Given a mock resource service with devcontainer "local/test-dc-rb" id "01TESTLIFECYCLE0000000210" at "/workspace/project"
    And a stopped container "01TESTLIFECYCLE0000000210"
    When I invoke CLI resource rebuild "local/test-dc-rb"
    Then the CLI exit code should be 0
    And the CLI output should contain "Rebuilt"

  Scenario: CLI rebuild rejects resource with no location
    Given a mock resource service with devcontainer "local/dc-no-loc" id "01TESTLIFECYCLE0000000211" with no location
    And a stopped container "01TESTLIFECYCLE0000000211"
    When I invoke CLI resource rebuild "local/dc-no-loc"
    Then the devcontainer CLI exit code should be non-zero
    And the CLI output should contain "no location"

  Scenario: CLI rebuild rejects non-devcontainer resource type
    Given a mock resource service with git-checkout "local/git-rb" id "01TESTLIFECYCLE0000000212"
    When I invoke CLI resource rebuild "local/git-rb"
    Then the devcontainer CLI exit code should be non-zero
    And the CLI output should contain "rebuild requires devcontainer"

  # ── R7: CLI test mock assertions ───────────────────────────

  Scenario: CLI stop calls stop_container with correct resource_id
    Given a mock resource service with devcontainer "local/test-dc-r7" id "01TESTLIFECYCLE0000000220" at "/workspace/project"
    And an active container "01TESTLIFECYCLE0000000220" with container ID "ctr-r7"
    When I invoke CLI resource stop "local/test-dc-r7"
    Then the CLI exit code should be 0
    And the CLI stop mock should have been called with "01TESTLIFECYCLE0000000220"

  Scenario: CLI rebuild calls rebuild_container with correct args
    Given a mock resource service with devcontainer "local/test-dc-r7rb" id "01TESTLIFECYCLE0000000221" at "/workspace/project"
    And a stopped container "01TESTLIFECYCLE0000000221"
    When I invoke CLI resource rebuild "local/test-dc-r7rb"
    Then the CLI exit code should be 0
    And the CLI rebuild mock should have been called with "01TESTLIFECYCLE0000000221" and "/workspace/project"

  # ── R8: DevcontainerHandler coverage ───────────────────────

  Scenario: DevcontainerHandler has expected class attributes and is instantiable
    Then DevcontainerHandler should have _default_strategy "none"
    And DevcontainerHandler should have _type_label "devcontainer"
    And DevcontainerHandler should be instantiable

  Scenario: DevcontainerHandler extends BaseResourceHandler and inherits resolve interface
    Then DevcontainerHandler should be a subclass of BaseResourceHandler
    And DevcontainerHandler instance should have a resolve method

  # ── R12: CLI state precondition validation ─────────────────

  Scenario: CLI stop rejects container not in running state
    Given a mock resource service with devcontainer "local/dc-det" id "01TESTLIFECYCLE0000000230" at "/workspace/project"
    And a lifecycle tracker for resource "01TESTLIFECYCLE0000000230"
    When I invoke CLI resource stop "local/dc-det"
    Then the devcontainer CLI exit code should be non-zero
    And the CLI output should contain "Cannot stop"

  Scenario: CLI rebuild rejects container in running state
    Given a mock resource service with devcontainer "local/dc-run" id "01TESTLIFECYCLE0000000231" at "/workspace/project"
    And an active container "01TESTLIFECYCLE0000000231" with container ID "ctr-rb-state"
    When I invoke CLI resource rebuild "local/dc-run"
    Then the devcontainer CLI exit code should be non-zero
    And the CLI output should contain "Cannot rebuild"

  # ── R14: stop_all return list assertion ────────────────────

  Scenario: Session cleanup returns list of stopped resource IDs
    Given a mock devcontainer CLI runner
    And an active container "01TESTLIFECYCLE0000000250" with container ID "ctr-r14a"
    And an active container "01TESTLIFECYCLE0000000251" with container ID "ctr-r14b"
    When I run session cleanup for session "session-r14"
    Then the cleanup stopped list should contain "01TESTLIFECYCLE0000000250"
    And the cleanup stopped list should contain "01TESTLIFECYCLE0000000251"

  # ── A2: Stop and rebuild accept --yes flag ─────────────────

  Scenario: CLI stop with --yes skips confirmation and calls stop_container
    Given a CLI-mockable running devcontainer resource "test-dc-yes-stop"
    When I invoke CLI resource stop "test-dc-yes-stop"
    Then the devcontainer CLI exit code should be 0
    And the CLI stop mock should have been called once

  Scenario: CLI rebuild with --yes skips confirmation and calls rebuild_container
    Given a CLI-mockable stopped devcontainer resource "test-dc-yes-rebuild"
    When I invoke CLI resource rebuild "test-dc-yes-rebuild"
    Then the devcontainer CLI exit code should be 0
    And the CLI rebuild mock should have been called once

  # ── Issue #2588: container-instance IS stoppable via CLI ────

  Scenario: CLI stop accepts container-instance type (issue #2588 fix)
    Given a mock resource service with container-instance "local/ctr-stop" id "01TESTLIFECYCLE0000000370" at "/workspace/project"
    And an active container "01TESTLIFECYCLE0000000370" with container ID "ctr-ci-stop"
    When I invoke CLI resource stop "local/ctr-stop"
    Then the CLI exit code should be 0
    And the CLI output should contain "Stopped"

  # ── F6-r6: CLI handler-level error paths ────────────────────

  Scenario: CLI stop handles NotFoundError from show_resource
    Given a mock resource service that raises NotFoundError for "local/missing"
    When I invoke CLI resource stop "local/missing"
    Then the devcontainer CLI exit code should be non-zero
    And the CLI output should contain "Resource not found"

  Scenario: CLI rebuild handles NotFoundError from show_resource
    Given a mock resource service that raises NotFoundError for "local/missing-rb"
    When I invoke CLI resource rebuild "local/missing-rb"
    Then the devcontainer CLI exit code should be non-zero
    And the CLI output should contain "Resource not found"

  Scenario: CLI stop handles RuntimeError from stop_container
    Given a mock resource service with devcontainer "local/dc-rterr" id "01TESTLIFECYCLE0000000500" at "/workspace/project"
    And an active container "01TESTLIFECYCLE0000000500" with container ID "ctr-rterr"
    And CLI stop_container mock that raises RuntimeError
    When I invoke CLI resource stop with error mock "local/dc-rterr"
    Then the devcontainer CLI exit code should be non-zero
    And the CLI output should contain "Stop failed"

  Scenario: CLI rebuild handles RuntimeError from rebuild_container
    Given a mock resource service with devcontainer "local/dc-rberr" id "01TESTLIFECYCLE0000000501" at "/workspace/project"
    And a stopped container "01TESTLIFECYCLE0000000501"
    And CLI rebuild_container mock that raises RuntimeError
    When I invoke CLI resource rebuild with error mock "local/dc-rberr"
    Then the devcontainer CLI exit code should be non-zero
    And the CLI output should contain "Rebuild failed"

  # ── R7-F1: Session-scoped container cleanup ────────────────

  Scenario: Session cleanup only stops containers belonging to that session
    Given a mock devcontainer CLI runner
    And a session-scoped active container "01TESTLIFECYCLE0000000600" with ID "ctr-s1" session "sess-A"
    And a session-scoped active container "01TESTLIFECYCLE0000000601" with ID "ctr-s2" session "sess-B"
    When I run session cleanup for session "sess-A"
    Then the container state for "01TESTLIFECYCLE0000000600" should be "stopped"
    And the container state for "01TESTLIFECYCLE0000000601" should be "running"

  Scenario: Session cleanup with no session_id stops all containers
    Given a mock devcontainer CLI runner
    And an active container "01TESTLIFECYCLE0000000610" with container ID "ctr-all1"
    And an active container "01TESTLIFECYCLE0000000611" with container ID "ctr-all2"
    When I run session cleanup with no session filter
    Then the container state for "01TESTLIFECYCLE0000000610" should be "stopped"
    And the container state for "01TESTLIFECYCLE0000000611" should be "stopped"

  # ── R8-F1: Eviction wired into production cleanup ────────────

  Scenario: Session cleanup triggers terminal tracker eviction
    Given a mock devcontainer CLI runner
    And 210 stopped container trackers in the registry
    And an active container "01TESTLIFECYCLE0000000650" with container ID "ctr-evict"
    When I run session cleanup for session "session-evict"
    Then the container state for "01TESTLIFECYCLE0000000650" should be "stopped"
    And the registry should have at most 200 terminal trackers

  # ── TEST-3: Coverage gap scenarios ──────────────────────────

  Scenario: list_active_containers_for_session returns only matching session
    Given a mock devcontainer CLI runner
    And a session-scoped active container "01TESTLIFECYCLE0000000700" with ID "ctr-ts3a" session "sess-X"
    And a session-scoped active container "01TESTLIFECYCLE0000000701" with ID "ctr-ts3b" session "sess-Y"
    When I list active containers for session "sess-X"
    Then the session container list should contain "01TESTLIFECYCLE0000000700"
    And the session container list should not contain "01TESTLIFECYCLE0000000701"

  Scenario: list_active_containers_for_session with empty session returns all
    Given a mock devcontainer CLI runner
    And an active container "01TESTLIFECYCLE0000000710" with container ID "ctr-ts3c"
    And an active container "01TESTLIFECYCLE0000000711" with container ID "ctr-ts3d"
    When I list active containers for an empty session
    Then the session container list should contain "01TESTLIFECYCLE0000000710"
    And the session container list should contain "01TESTLIFECYCLE0000000711"

  Scenario: list_active_containers_for_session includes unscoped containers
    Given a mock devcontainer CLI runner
    And an active container "01TESTLIFECYCLE0000000720" with container ID "ctr-unscoped"
    And a session-scoped active container "01TESTLIFECYCLE0000000721" with ID "ctr-scoped" session "sess-Z"
    When I list active containers for session "sess-Z"
    Then the session container list should contain "01TESTLIFECYCLE0000000720"
    And the session container list should contain "01TESTLIFECYCLE0000000721"

  # ── R7-F4: Session close cleanup without session service ────

  Scenario: Session close cleans up containers even without session service
    Given a facade with no session service
    And a session-scoped active container "01TESTLIFECYCLE0000000630" with no docker ID session "sess-f4"
    When I close session "sess-f4" via the facade
    Then the container state for "01TESTLIFECYCLE0000000630" should be "stopped"
