@phase2 @plan_lifecycle @rollback
Feature: PlanLifecycleService rollback_plan method
  As a developer using the plan lifecycle service
  I want a rollback_plan method on PlanLifecycleService
  So that rollback operations go through the service layer with proper
  state validation and domain event emission

  # ───────────────────────────────────────────────────────────
  # Service method existence and basic delegation
  # ───────────────────────────────────────────────────────────

  Scenario: rollback_plan delegates to CheckpointService and returns RollbackResult
    Given plr-a plan lifecycle service with a mock checkpoint service
    And plr-a plan in Execute phase with a sandbox
    And plr-a checkpoint exists for the plan
    When plr-I call rollback_plan with the plan id and checkpoint id
    Then plr-the rollback should succeed
    And plr-the result should be a RollbackResult
    And plr-the checkpoint service selective_rollback should have been called

  Scenario: rollback_plan raises PlanError when checkpoint_service is not configured
    Given plr-a plan lifecycle service without a checkpoint service
    And plr-a plan in Execute phase
    When plr-I call rollback_plan with the plan id and checkpoint id
    Then plr-a PlanError should be raised with "requires a CheckpointService"

  # ───────────────────────────────────────────────────────────
  # State validation
  # ───────────────────────────────────────────────────────────

  Scenario: rollback_plan rejects a plan in APPLIED terminal state
    Given plr-a plan lifecycle service with a mock checkpoint service
    And plr-a plan in APPLIED terminal state
    When plr-I call rollback_plan with the plan id and checkpoint id
    Then plr-a PlanError should be raised with "terminal state"
    And plr-the checkpoint service selective_rollback should NOT have been called

  Scenario: rollback_plan rejects a plan in CANCELLED terminal state
    Given plr-a plan lifecycle service with a mock checkpoint service
    And plr-a plan in CANCELLED terminal state
    When plr-I call rollback_plan with the plan id and checkpoint id
    Then plr-a PlanError should be raised with "terminal state"
    And plr-the checkpoint service selective_rollback should NOT have been called

  Scenario: rollback_plan accepts a plan in Execute/PROCESSING state
    Given plr-a plan lifecycle service with a mock checkpoint service
    And plr-a plan in Execute/PROCESSING state with a sandbox
    And plr-a checkpoint exists for the plan
    When plr-I call rollback_plan with the plan id and checkpoint id
    Then plr-the rollback should succeed

  Scenario: rollback_plan accepts a plan in Execute/QUEUED state
    Given plr-a plan lifecycle service with a mock checkpoint service
    And plr-a plan in Execute/QUEUED state with a sandbox
    And plr-a checkpoint exists for the plan
    When plr-I call rollback_plan with the plan id and checkpoint id
    Then plr-the rollback should succeed

  Scenario: rollback_plan accepts a plan in Strategize phase
    Given plr-a plan lifecycle service with a mock checkpoint service
    And plr-a plan in Strategize/QUEUED state with a sandbox
    And plr-a checkpoint exists for the plan
    When plr-I call rollback_plan with the plan id and checkpoint id
    Then plr-the rollback should succeed

  # ───────────────────────────────────────────────────────────
  # Domain event emission
  # ───────────────────────────────────────────────────────────

  Scenario: rollback_plan emits PLAN_ROLLED_BACK domain event on success
    Given plr-a plan lifecycle service with a mock checkpoint service and event bus
    And plr-a plan in Execute phase with a sandbox
    And plr-a checkpoint exists for the plan
    When plr-I call rollback_plan with the plan id and checkpoint id
    Then plr-the rollback should succeed
    And plr-a PLAN_ROLLED_BACK domain event should have been emitted
    And plr-the event should contain the checkpoint_id

  Scenario: rollback_plan does not emit events when event_bus is None
    Given plr-a plan lifecycle service with a mock checkpoint service but no event bus
    And plr-a plan in Execute phase with a sandbox
    And plr-a checkpoint exists for the plan
    When plr-I call rollback_plan with the plan id and checkpoint id
    Then plr-the rollback should succeed

  # ───────────────────────────────────────────────────────────
  # CheckpointService exception propagation
  # ───────────────────────────────────────────────────────────

  Scenario: rollback_plan propagates ResourceNotFoundError from checkpoint service
    Given plr-a plan lifecycle service with a checkpoint service that raises ResourceNotFoundError
    And plr-a plan in Execute phase with a sandbox
    When plr-I call rollback_plan with the plan id and checkpoint id
    Then plr-a ResourceNotFoundError should be raised
    And plr-the checkpoint service selective_rollback should have been called

  Scenario: rollback_plan propagates BusinessRuleViolation from checkpoint service
    Given plr-a plan lifecycle service with a checkpoint service that raises BusinessRuleViolation
    And plr-a plan in Execute phase with a sandbox
    When plr-I call rollback_plan with the plan id and checkpoint id
    Then plr-a BusinessRuleViolation should be raised
    And plr-the checkpoint service selective_rollback should have been called

  # ───────────────────────────────────────────────────────────
  # NotFoundError propagation
  # ───────────────────────────────────────────────────────────

  Scenario: rollback_plan raises NotFoundError for non-existent plan
    Given plr-a plan lifecycle service with a mock checkpoint service
    When plr-I call rollback_plan with a non-existent plan id
    Then plr-a NotFoundError should be raised
