///|
pub(all) struct DryRunResult {
  plan : RoutinePlan
  events : Array[RoutineEvent]
  record : @domain.AnalysisRecord
} derive(Debug, Eq, ToJson, FromJson)

///|
pub fn run_dry_analysis(
  request : RoutineRequest,
  diagnosis : @domain.Stage1Diagnosis,
  decision : @domain.Stage2Decision,
) -> DryRunResult {
  let plan = routine_plan(request.run_id)
  let routed = @tools.diagnosis_with_routing(diagnosis)
  let record = @domain.empty_analysis_record(request.run_id, request.snapshot)
    .with_stage1(routed)
    .with_validation(@tools.validate_stage1(routed))
    .with_stage2(decision)
    .with_validation(@tools.validate_stage2(decision))
    .persisted()
  { plan, events: phase_events(request.run_id, plan.phases), record }
}

///|
pub fn plan_analysis(
  run_id : @domain.RunId,
  snapshot : @domain.KlineSnapshot,
  diagnosis : @domain.Stage1Diagnosis,
  decision : @domain.Stage2Decision,
) -> DryRunResult {
  run_dry_analysis(
    routine_request(run_id, "fixture dry run", snapshot),
    diagnosis,
    decision,
  )
}

///|
pub fn dry_response(
  request : RoutineRequest,
  diagnosis : @domain.Stage1Diagnosis,
  decision : @domain.Stage2Decision,
) -> RoutineResponse {
  let result = run_dry_analysis(request, diagnosis, decision)
  { request, plan: result.plan, events: result.events, record: result.record }
}