///|
pub(all) enum AnalysisRunStatus {
  Completed
  AwaitingMarketData
} derive(Debug, Eq, ToJson, FromJson)

///|
pub(all) struct AnalysisRunRequest {
  run_id : @domain.RunId
  operator_request : String
  market : @data.MarketSourceRequest
  gateway : @model.ModelGateway
  diagnosis : @domain.Stage1Diagnosis
  decision : @domain.Stage2Decision
} derive(Debug, Eq, ToJson, FromJson)

///|
pub(all) struct AnalysisRunBundle {
  request : AnalysisRunRequest
  status : AnalysisRunStatus
  market_fetch : @data.MarketFetchResult
  projection : @execution.DryExecutionProjection?
  chart_frame : @chart.ChartFrame?
  write_plan : @book.BookWritePlan?
  book_commit : @book.BookCommitReport?
} derive(Debug, Eq, ToJson, FromJson)

///|
pub fn analysis_run_request(
  run_id : @domain.RunId,
  operator_request : String,
  market : @data.MarketSourceRequest,
  gateway : @model.ModelGateway,
  diagnosis : @domain.Stage1Diagnosis,
  decision : @domain.Stage2Decision,
) -> AnalysisRunRequest {
  { run_id, operator_request, market, gateway, diagnosis, decision }
}

///|
fn analysis_bundle_from_fetch(
  request : AnalysisRunRequest,
  market_fetch : @data.MarketFetchResult,
) -> AnalysisRunBundle {
  match market_fetch.snapshot {
    Some(snapshot) => {
      let routine_request = @routine.routine_request(
        request.run_id,
        request.operator_request,
        snapshot,
      )
      let projection = @execution.dry_execution_projection(
        routine_request,
        request.gateway,
        request.diagnosis,
        request.decision,
      )
      let chart_frame = @chart.render_chart_frame(
        snapshot,
        decision=request.decision,
        structure_levels=projection.structure_levels,
      )
      let write_plan = @book.dry_projection_write_plan(projection)
      let book_commit = @book.prepare_book_commit_report(write_plan)
      {
        request,
        status: Completed,
        market_fetch,
        projection: Some(projection),
        chart_frame: Some(chart_frame),
        write_plan: Some(write_plan),
        book_commit: Some(book_commit),
      }
    }
    None =>
      {
        request,
        status: AwaitingMarketData,
        market_fetch,
        projection: None,
        chart_frame: None,
        write_plan: None,
        book_commit: None,
      }
  }
}

///|
pub fn run_analysis_bundle(request : AnalysisRunRequest) -> AnalysisRunBundle {
  analysis_bundle_from_fetch(
    request,
    @data.fetch_kline_snapshot(request.market),
  )
}

///|
pub fn run_analysis_bundle_with_snapshot(
  request : AnalysisRunRequest,
  snapshot : @domain.KlineSnapshot,
) -> AnalysisRunBundle {
  analysis_bundle_from_fetch(
    request,
    @data.ingest_market_snapshot(
      @data.market_ingest_input(request.market, snapshot),
    ),
  )
}