// @generated — Generated by `cargo xtask machine-codegen --all`.
#![allow(
    clippy::unwrap_used,
    clippy::expect_used,
    clippy::panic,
    clippy::implicit_clone,
    clippy::unnecessary_cast,
    clippy::redundant_clone
)]

pub fn schema() -> meerkat_machine_schema::MachineSchema {
    meerkat_machine_schema::catalog::dsl::dsl_work_graph_lifecycle_machine()
}

#[derive(
    Debug,
    Clone,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    serde::Serialize,
    serde::Deserialize,
)]
pub struct WorkDependencyPathKey(pub String);
impl From<String> for WorkDependencyPathKey {
    fn from(value: String) -> Self {
        Self(value)
    }
}
impl From<&str> for WorkDependencyPathKey {
    fn from(value: &str) -> Self {
        Self(value.to_owned())
    }
}
impl std::fmt::Display for WorkDependencyPathKey {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(&self.0)
    }
}
#[derive(
    Debug,
    Clone,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    serde::Serialize,
    serde::Deserialize,
)]
pub struct WorkEdgeKey(pub String);
impl From<String> for WorkEdgeKey {
    fn from(value: String) -> Self {
        Self(value)
    }
}
impl From<&str> for WorkEdgeKey {
    fn from(value: &str) -> Self {
        Self(value.to_owned())
    }
}
impl std::fmt::Display for WorkEdgeKey {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(&self.0)
    }
}
#[allow(non_camel_case_types)]
#[derive(
    Debug,
    Clone,
    Copy,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    serde::Serialize,
    serde::Deserialize,
)]
pub enum WorkEdgeKind {
    #[default]
    #[serde(rename = "Blocks")]
    Blocks,
    #[serde(rename = "Parent")]
    Parent,
    #[serde(rename = "Related")]
    Related,
    #[serde(rename = "Supersedes")]
    Supersedes,
    #[serde(rename = "DerivedFrom")]
    DerivedFrom,
}
impl WorkEdgeKind {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Blocks => "Blocks",
            Self::Parent => "Parent",
            Self::Related => "Related",
            Self::Supersedes => "Supersedes",
            Self::DerivedFrom => "DerivedFrom",
        }
    }
}
impl std::convert::TryFrom<&str> for WorkEdgeKind {
    type Error = String;
    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value {
            "Blocks" => Ok(Self::Blocks),
            "Parent" => Ok(Self::Parent),
            "Related" => Ok(Self::Related),
            "Supersedes" => Ok(Self::Supersedes),
            "DerivedFrom" => Ok(Self::DerivedFrom),
            other => Err(format!("invalid WorkEdgeKind value `{other}`")),
        }
    }
}
impl std::convert::TryFrom<String> for WorkEdgeKind {
    type Error = String;
    fn try_from(value: String) -> Result<Self, Self::Error> {
        Self::try_from(value.as_str())
    }
}
impl std::fmt::Display for WorkEdgeKind {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.as_str())
    }
}
#[derive(
    Debug,
    Clone,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    serde::Serialize,
    serde::Deserialize,
)]
pub struct WorkItemKey(pub String);
impl From<String> for WorkItemKey {
    fn from(value: String) -> Self {
        Self(value)
    }
}
impl From<&str> for WorkItemKey {
    fn from(value: &str) -> Self {
        Self(value.to_owned())
    }
}
impl std::fmt::Display for WorkItemKey {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(&self.0)
    }
}
#[allow(non_camel_case_types)]
#[derive(
    Debug,
    Clone,
    Copy,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    serde::Serialize,
    serde::Deserialize,
)]
pub enum WorkLifecycleState {
    #[default]
    #[serde(rename = "Absent")]
    Absent,
    #[serde(rename = "Open")]
    Open,
    #[serde(rename = "InProgress")]
    InProgress,
    #[serde(rename = "Blocked")]
    Blocked,
    #[serde(rename = "Completed")]
    Completed,
    #[serde(rename = "Cancelled")]
    Cancelled,
    #[serde(rename = "Failed")]
    Failed,
}
impl WorkLifecycleState {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Absent => "Absent",
            Self::Open => "Open",
            Self::InProgress => "InProgress",
            Self::Blocked => "Blocked",
            Self::Completed => "Completed",
            Self::Cancelled => "Cancelled",
            Self::Failed => "Failed",
        }
    }
}
impl std::convert::TryFrom<&str> for WorkLifecycleState {
    type Error = String;
    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value {
            "Absent" => Ok(Self::Absent),
            "Open" => Ok(Self::Open),
            "InProgress" => Ok(Self::InProgress),
            "Blocked" => Ok(Self::Blocked),
            "Completed" => Ok(Self::Completed),
            "Cancelled" => Ok(Self::Cancelled),
            "Failed" => Ok(Self::Failed),
            other => Err(format!("invalid WorkLifecycleState value `{other}`")),
        }
    }
}
impl std::convert::TryFrom<String> for WorkLifecycleState {
    type Error = String;
    fn try_from(value: String) -> Result<Self, Self::Error> {
        Self::try_from(value.as_str())
    }
}
impl std::fmt::Display for WorkLifecycleState {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.as_str())
    }
}
pub type WorkOwnerKey = meerkat_machine_schema::catalog::dsl::workgraph_lifecycle::WorkOwnerKey;

pub trait Context {}
pub struct EmptyContext;
impl Context for EmptyContext {}

#[allow(non_camel_case_types)]
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum Phase {
    Absent,
    Open,
    InProgress,
    Blocked,
    Completed,
    Cancelled,
    Failed,
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct State {
    pub phase: Phase,
    pub revision: u64,
    pub unresolved_blocker_count: u64,
    pub topology_item_keys: std::collections::BTreeSet<WorkItemKey>,
    pub topology_edge_keys: std::collections::BTreeSet<WorkEdgeKey>,
    pub blocks_reachability: std::collections::BTreeSet<WorkDependencyPathKey>,
    pub parent_reachability: std::collections::BTreeSet<WorkDependencyPathKey>,
    pub claim_owner_key: Option<WorkOwnerKey>,
    pub claimed_at_utc_ms: Option<u64>,
    pub lease_expires_at_utc_ms: Option<u64>,
    pub due_at_utc_ms: Option<u64>,
    pub not_before_utc_ms: Option<u64>,
    pub snoozed_until_utc_ms: Option<u64>,
    pub terminal_at_utc_ms: Option<u64>,
    pub evidence_count: u64,
}
impl Default for State {
    fn default() -> Self {
        initial_state()
    }
}

pub mod inputs {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct CreateOpen {
        pub due_at_utc_ms: Option<u64>,
        pub not_before_utc_ms: Option<u64>,
        pub snoozed_until_utc_ms: Option<u64>,
        pub unresolved_blocker_count: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct CreateBlocked {
        pub due_at_utc_ms: Option<u64>,
        pub not_before_utc_ms: Option<u64>,
        pub snoozed_until_utc_ms: Option<u64>,
        pub unresolved_blocker_count: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Update {
        pub expected_revision: u64,
        pub due_at_utc_ms: Option<u64>,
        pub not_before_utc_ms: Option<u64>,
        pub snoozed_until_utc_ms: Option<u64>,
        pub unresolved_blocker_count: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Claim {
        pub expected_revision: u64,
        pub owner_key: WorkOwnerKey,
        pub now_utc_ms: u64,
        pub lease_expires_at_utc_ms: Option<u64>,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Release {
        pub expected_revision: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Block {
        pub expected_revision: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct RefreshEligibility {
        pub unresolved_blocker_count: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct ValidateLink {
        pub kind: WorkEdgeKind,
        pub from_item_key: WorkItemKey,
        pub to_item_key: WorkItemKey,
        pub edge_key: WorkEdgeKey,
        pub reverse_path_key: WorkDependencyPathKey,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct CloseCompleted {
        pub expected_revision: u64,
        pub at_utc_ms: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct CloseCancelled {
        pub expected_revision: u64,
        pub at_utc_ms: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct CloseFailed {
        pub expected_revision: u64,
        pub at_utc_ms: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct AddEvidence {
        pub expected_revision: u64,
    }
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum Input {
    CreateOpen(inputs::CreateOpen),
    CreateBlocked(inputs::CreateBlocked),
    Update(inputs::Update),
    Claim(inputs::Claim),
    Release(inputs::Release),
    Block(inputs::Block),
    RefreshEligibility(inputs::RefreshEligibility),
    ValidateLink(inputs::ValidateLink),
    CloseCompleted(inputs::CloseCompleted),
    CloseCancelled(inputs::CloseCancelled),
    CloseFailed(inputs::CloseFailed),
    AddEvidence(inputs::AddEvidence),
}
impl Input {
    pub fn kind(&self) -> InputKind {
        match self {
            Self::CreateOpen(_) => InputKind::CreateOpen,
            Self::CreateBlocked(_) => InputKind::CreateBlocked,
            Self::Update(_) => InputKind::Update,
            Self::Claim(_) => InputKind::Claim,
            Self::Release(_) => InputKind::Release,
            Self::Block(_) => InputKind::Block,
            Self::RefreshEligibility(_) => InputKind::RefreshEligibility,
            Self::ValidateLink(_) => InputKind::ValidateLink,
            Self::CloseCompleted(_) => InputKind::CloseCompleted,
            Self::CloseCancelled(_) => InputKind::CloseCancelled,
            Self::CloseFailed(_) => InputKind::CloseFailed,
            Self::AddEvidence(_) => InputKind::AddEvidence,
        }
    }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum InputKind {
    CreateOpen,
    CreateBlocked,
    Update,
    Claim,
    Release,
    Block,
    RefreshEligibility,
    ValidateLink,
    CloseCompleted,
    CloseCancelled,
    CloseFailed,
    AddEvidence,
}

pub mod effects {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Created {}
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Updated {}
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Claimed {
        pub owner_key: WorkOwnerKey,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Released {}
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Blocked {}
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct LinkValidated {}
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Closed {
        pub terminal_state: WorkLifecycleState,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct EvidenceAdded {}
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum Effect {
    Created(effects::Created),
    Updated(effects::Updated),
    Claimed(effects::Claimed),
    Released(effects::Released),
    Blocked(effects::Blocked),
    LinkValidated(effects::LinkValidated),
    Closed(effects::Closed),
    EvidenceAdded(effects::EvidenceAdded),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum EffectKind {
    Created,
    Updated,
    Claimed,
    Released,
    Blocked,
    LinkValidated,
    Closed,
    EvidenceAdded,
}

#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum TransitionId {
    CreateOpen,
    CreateBlocked,
    UpdateOpen,
    UpdateInProgress,
    UpdateBlocked,
    ClaimOpen,
    ClaimExpiredInProgress,
    ReleaseInProgress,
    BlockOpen,
    BlockInProgress,
    BlockBlocked,
    RefreshEligibilityOpen,
    RefreshEligibilityInProgress,
    RefreshEligibilityBlocked,
    ValidateLink,
    CloseOpenCompleted,
    CloseInProgressCompleted,
    CloseBlockedCompleted,
    CloseOpenCancelled,
    CloseInProgressCancelled,
    CloseBlockedCancelled,
    CloseOpenFailed,
    CloseInProgressFailed,
    CloseBlockedFailed,
    AddEvidenceOpen,
    AddEvidenceInProgress,
    AddEvidenceBlocked,
    AddEvidenceCompleted,
    AddEvidenceCancelled,
    AddEvidenceFailed,
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum GuardId {
    None,
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum HelperId {
    None,
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct GuardRejection {
    pub transition_id: TransitionId,
    pub guard_id: GuardId,
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum TriggerDiscriminant {
    Input(InputKind),
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum TransitionRefusal {
    NoMatchingTransition {
        phase: Phase,
        trigger: TriggerDiscriminant,
    },
    GuardRejected {
        rejections: Vec<GuardRejection>,
    },
    AmbiguousTransition {
        transitions: Vec<TransitionId>,
    },
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum KernelError {
    ContextViolation {
        transition_id: TransitionId,
        detail: String,
    },
    HelperEvaluation {
        helper_id: HelperId,
        detail: String,
    },
    CodegenInvariant {
        detail: String,
    },
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum TransitionError {
    Refusal(TransitionRefusal),
    Kernel(KernelError),
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct Outcome {
    pub transition_id: TransitionId,
    pub next_state: State,
    pub effects: Vec<Effect>,
}

pub mod helpers {
    #[allow(unused_imports)]
    use super::*;
    pub fn none<C: Context>(_: &State, context: &C) -> Result<(), KernelError> {
        let _ = context;
        Ok(())
    }
}

pub fn initial_state() -> State {
    State {
        phase: Phase::Absent,
        revision: 0,
        unresolved_blocker_count: 0,
        topology_item_keys: Default::default(),
        topology_edge_keys: Default::default(),
        blocks_reachability: Default::default(),
        parent_reachability: Default::default(),
        claim_owner_key: None,
        claimed_at_utc_ms: None,
        lease_expires_at_utc_ms: None,
        due_at_utc_ms: None,
        not_before_utc_ms: None,
        snoozed_until_utc_ms: None,
        terminal_at_utc_ms: None,
        evidence_count: 0,
    }
}
