///|
pub(all) enum RuntimeStatus {
  Proposed
  Ready
  Active
  Waiting
  Blocked
  Review
  Accepted
  Failed
  Cancelled
  Superseded
} derive(Debug, Eq, Compare, Hash, ToJson)

///|
pub fn RuntimeStatus::id(self : RuntimeStatus) -> String {
  match self {
    Proposed => "proposed"
    Ready => "ready"
    Active => "active"
    Waiting => "waiting"
    Blocked => "blocked"
    Review => "review"
    Accepted => "accepted"
    Failed => "failed"
    Cancelled => "cancelled"
    Superseded => "superseded"
  }
}

///|
pub fn RuntimeStatus::is_terminal(self : RuntimeStatus) -> Bool {
  match self {
    Accepted | Failed | Cancelled | Superseded => true
    _ => false
  }
}

///|
pub(all) enum EventKind {
  RunCreated
  ItemRegistered
  ItemReady
  ItemStarted
  ItemWaiting
  ItemBlocked
  ItemReviewRequested
  ItemAccepted
  ItemFailed
  ItemCancelled
  ItemSuperseded
  ArtifactAttached
  ApprovalGranted
  AttemptSubmitted
  AttemptReconciled
  CheckpointReused
} derive(Debug, Eq, Compare, Hash, ToJson)

///|
pub fn EventKind::id(self : EventKind) -> String {
  match self {
    RunCreated => "run-created"
    ItemRegistered => "item-registered"
    ItemReady => "item-ready"
    ItemStarted => "item-started"
    ItemWaiting => "item-waiting"
    ItemBlocked => "item-blocked"
    ItemReviewRequested => "item-review-requested"
    ItemAccepted => "item-accepted"
    ItemFailed => "item-failed"
    ItemCancelled => "item-cancelled"
    ItemSuperseded => "item-superseded"
    ArtifactAttached => "artifact-attached"
    ApprovalGranted => "approval-granted"
    AttemptSubmitted => "attempt-submitted"
    AttemptReconciled => "attempt-reconciled"
    CheckpointReused => "checkpoint-reused"
  }
}

///|
pub(all) struct RuntimeEvent {
  sequence : Int
  event_id : String
  run_id : String
  work_item_id : String
  kind : EventKind
  product_id : String
  declaration_id : String
  book_id : String
  declaration_revision : String
  source_digest : String
  requested_authority : String
  acceptance_criteria : Array[String]
  operation : String
  input_contracts : Array[String]
  output_contracts : Array[String]
  required_claim : String
  input_artifacts : Array[String]
  timeout_ms : Int
  request_id : String
  result_id : String
  attempt_id : String
  idempotency_key : String
  external_job_id : String
  attempt_status : String
  input_digest : String
  output_digest : String
  output_artifacts : Array[String]
  error_kind : String
  compensable : Bool
  depends_on : Array[String]
  detail : String
  artifact_id : String
  authority_id : String
  recorded_at : String
} derive(Debug, Eq, ToJson)

///|
pub(all) struct RuntimeItem {
  work_item_id : String
  declaration_id : String
  product_id : String
  requested_authority : String
  acceptance_criteria : Array[String]
  operation : String
  input_contracts : Array[String]
  output_contracts : Array[String]
  required_claim : String
  input_artifacts : Array[String]
  timeout_ms : Int
  depends_on : Array[String]
  mut status : RuntimeStatus
  mut attempt_count : Int
  mut request_id : String
  mut result_id : String
  mut active_attempt_id : String
  mut idempotency_key : String
  mut external_job_id : String
  mut attempt_status : String
  mut input_digest : String
  mut output_digest : String
  mut error_kind : String
  mut compensable : Bool
  mut blocker : String
  mut acceptance_review_id : String
  mut acceptance_review_artifact : String
  mut acceptance_reviewer_id : String
  artifacts : Array[String]
  approvals : Array[String]
} derive(Debug, Eq, ToJson)

///|
pub(all) struct RunProjection {
  run_id : String
  mut book_id : String
  mut declaration_revision : String
  mut source_digest : String
  mut last_sequence : Int
  items : Array[RuntimeItem]
  applied_event_ids : Array[String]
  applied_events : Array[RuntimeEvent]
  mut outcome : String
} derive(Debug, Eq, ToJson)

///|
pub(all) suberror FlowError {
  EmptyEventId
  EmptyRunId
  InvalidSequence(expected~ : Int, actual~ : Int)
  ConflictingDuplicateEvent(String)
  RunIdMismatch(expected~ : String, actual~ : String)
  MissingWorkItem(String)
  DuplicateWorkItem(String)
  InvalidTransition(item_id~ : String, from~ : String, event~ : String)
  DependencyNotAccepted(item_id~ : String, dependency_id~ : String)
  MissingArtifactId(String)
  MissingAuthorityId(String)
  MissingRunSource(String)
  MissingDeclarationId(String)
  MissingAcceptanceCriteria(String)
  InvalidAuthority(item_id~ : String, authority~ : String)
  SourceContextMismatch(field~ : String, expected~ : String, actual~ : String)
  MissingAttemptField(item_id~ : String, field~ : String)
  AttemptIdentityMismatch(
    item_id~ : String,
    expected~ : String,
    actual~ : String
  )
  UnsupportedAttemptStatus(item_id~ : String, status~ : String)
  MissingAcceptanceReview(String)
  MissingAcceptanceReviewField(item_id~ : String, field~ : String)
} derive(Debug, Eq, ToJson)