// @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,
    clippy::zero_sized_map_values
)]

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

#[allow(non_camel_case_types)]
#[derive(
    Debug,
    Clone,
    Copy,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    serde::Serialize,
    serde::Deserialize,
)]
pub enum MisfirePolicy {
    #[default]
    #[serde(rename = "Skip")]
    Skip,
    #[serde(rename = "CatchUpWithin")]
    CatchUpWithin,
}
impl MisfirePolicy {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Skip => "Skip",
            Self::CatchUpWithin => "CatchUpWithin",
        }
    }
}
impl std::convert::TryFrom<&str> for MisfirePolicy {
    type Error = String;
    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value {
            "Skip" => Ok(Self::Skip),
            "CatchUpWithin" => Ok(Self::CatchUpWithin),
            other => Err(format!("invalid MisfirePolicy value `{other}`")),
        }
    }
}
impl std::convert::TryFrom<String> for MisfirePolicy {
    type Error = String;
    fn try_from(value: String) -> Result<Self, Self::Error> {
        Self::try_from(value.as_str())
    }
}
impl std::fmt::Display for MisfirePolicy {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.as_str())
    }
}
#[allow(non_camel_case_types)]
#[derive(
    Debug,
    Clone,
    Copy,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    serde::Serialize,
    serde::Deserialize,
)]
pub enum MissingTargetPolicy {
    #[default]
    #[serde(rename = "MarkMisfired")]
    MarkMisfired,
    #[serde(rename = "Skip")]
    Skip,
}
impl MissingTargetPolicy {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::MarkMisfired => "MarkMisfired",
            Self::Skip => "Skip",
        }
    }
}
impl std::convert::TryFrom<&str> for MissingTargetPolicy {
    type Error = String;
    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value {
            "MarkMisfired" => Ok(Self::MarkMisfired),
            "Skip" => Ok(Self::Skip),
            other => Err(format!("invalid MissingTargetPolicy value `{other}`")),
        }
    }
}
impl std::convert::TryFrom<String> for MissingTargetPolicy {
    type Error = String;
    fn try_from(value: String) -> Result<Self, Self::Error> {
        Self::try_from(value.as_str())
    }
}
impl std::fmt::Display for MissingTargetPolicy {
    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 OccurrenceId(pub String);
impl From<String> for OccurrenceId {
    fn from(value: String) -> Self {
        Self(value)
    }
}
impl From<&str> for OccurrenceId {
    fn from(value: &str) -> Self {
        Self(value.to_owned())
    }
}
impl std::fmt::Display for OccurrenceId {
    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 OverlapPolicy {
    #[default]
    #[serde(rename = "AllowConcurrent")]
    AllowConcurrent,
    #[serde(rename = "SkipIfRunning")]
    SkipIfRunning,
}
impl OverlapPolicy {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::AllowConcurrent => "AllowConcurrent",
            Self::SkipIfRunning => "SkipIfRunning",
        }
    }
}
impl std::convert::TryFrom<&str> for OverlapPolicy {
    type Error = String;
    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value {
            "AllowConcurrent" => Ok(Self::AllowConcurrent),
            "SkipIfRunning" => Ok(Self::SkipIfRunning),
            other => Err(format!("invalid OverlapPolicy value `{other}`")),
        }
    }
}
impl std::convert::TryFrom<String> for OverlapPolicy {
    type Error = String;
    fn try_from(value: String) -> Result<Self, Self::Error> {
        Self::try_from(value.as_str())
    }
}
impl std::fmt::Display for OverlapPolicy {
    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 ScheduleId(pub String);
impl From<String> for ScheduleId {
    fn from(value: String) -> Self {
        Self(value)
    }
}
impl From<&str> for ScheduleId {
    fn from(value: &str) -> Self {
        Self(value.to_owned())
    }
}
impl std::fmt::Display for ScheduleId {
    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 ScheduleLifecycleState {
    #[default]
    #[serde(rename = "Active")]
    Active,
    #[serde(rename = "Paused")]
    Paused,
    #[serde(rename = "Deleted")]
    Deleted,
}
impl ScheduleLifecycleState {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Active => "Active",
            Self::Paused => "Paused",
            Self::Deleted => "Deleted",
        }
    }
}
impl std::convert::TryFrom<&str> for ScheduleLifecycleState {
    type Error = String;
    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value {
            "Active" => Ok(Self::Active),
            "Paused" => Ok(Self::Paused),
            "Deleted" => Ok(Self::Deleted),
            other => Err(format!("invalid ScheduleLifecycleState value `{other}`")),
        }
    }
}
impl std::convert::TryFrom<String> for ScheduleLifecycleState {
    type Error = String;
    fn try_from(value: String) -> Result<Self, Self::Error> {
        Self::try_from(value.as_str())
    }
}
impl std::fmt::Display for ScheduleLifecycleState {
    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 TargetBindingId(pub String);
impl From<String> for TargetBindingId {
    fn from(value: String) -> Self {
        Self(value)
    }
}
impl From<&str> for TargetBindingId {
    fn from(value: &str) -> Self {
        Self(value.to_owned())
    }
}
impl std::fmt::Display for TargetBindingId {
    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 TriggerKey(pub String);
impl From<String> for TriggerKey {
    fn from(value: String) -> Self {
        Self(value)
    }
}
impl From<&str> for TriggerKey {
    fn from(value: &str) -> Self {
        Self(value.to_owned())
    }
}
impl std::fmt::Display for TriggerKey {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(&self.0)
    }
}

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 {
    Active,
    Paused,
    Deleted,
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct State {
    pub phase: Phase,
    pub schedule_id: ScheduleId,
    pub revision: u64,
    pub trigger_key: TriggerKey,
    pub target_binding_key: TargetBindingId,
    pub misfire_policy: MisfirePolicy,
    pub overlap_policy: OverlapPolicy,
    pub missing_target_policy: MissingTargetPolicy,
    pub planning_horizon_days: u64,
    pub planning_horizon_occurrences: u64,
    pub planning_cursor_utc_ms: Option<u64>,
    pub next_occurrence_ordinal: u64,
    pub superseded_ack_ids: std::collections::BTreeSet<OccurrenceId>,
}
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 Create {
        pub schedule_id: ScheduleId,
        pub trigger_key: TriggerKey,
        pub target_binding_key: TargetBindingId,
        pub misfire_policy: MisfirePolicy,
        pub overlap_policy: OverlapPolicy,
        pub missing_target_policy: MissingTargetPolicy,
        pub planning_horizon_days: Option<u64>,
        pub planning_horizon_occurrences: Option<u64>,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Revise {
        pub trigger_key: TriggerKey,
        pub target_binding_key: TargetBindingId,
        pub misfire_policy: MisfirePolicy,
        pub overlap_policy: OverlapPolicy,
        pub missing_target_policy: MissingTargetPolicy,
        pub planning_horizon_days: u64,
        pub planning_horizon_occurrences: u64,
        pub at_utc_ms: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct UpdatePlanningConfig {
        pub planning_horizon_days: u64,
        pub planning_horizon_occurrences: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct RecordPlanningWindow {
        pub planning_cursor_utc_ms: u64,
        pub next_occurrence_ordinal: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct SyncTargetSnapshot {
        pub target_binding_key: TargetBindingId,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Pause {
        pub at_utc_ms: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Resume {
        pub at_utc_ms: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct Delete {
        pub at_utc_ms: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct ConfirmOccurrencesSuperseded {
        pub occurrence_id: OccurrenceId,
        pub superseding_revision: u64,
    }
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum Input {
    Create(inputs::Create),
    Revise(inputs::Revise),
    UpdatePlanningConfig(inputs::UpdatePlanningConfig),
    RecordPlanningWindow(inputs::RecordPlanningWindow),
    SyncTargetSnapshot(inputs::SyncTargetSnapshot),
    Pause(inputs::Pause),
    Resume(inputs::Resume),
    Delete(inputs::Delete),
    ConfirmOccurrencesSuperseded(inputs::ConfirmOccurrencesSuperseded),
}
impl Input {
    pub fn kind(&self) -> InputKind {
        match self {
            Self::Create(_) => InputKind::Create,
            Self::Revise(_) => InputKind::Revise,
            Self::UpdatePlanningConfig(_) => InputKind::UpdatePlanningConfig,
            Self::RecordPlanningWindow(_) => InputKind::RecordPlanningWindow,
            Self::SyncTargetSnapshot(_) => InputKind::SyncTargetSnapshot,
            Self::Pause(_) => InputKind::Pause,
            Self::Resume(_) => InputKind::Resume,
            Self::Delete(_) => InputKind::Delete,
            Self::ConfirmOccurrencesSuperseded(_) => InputKind::ConfirmOccurrencesSuperseded,
        }
    }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum InputKind {
    Create,
    Revise,
    UpdatePlanningConfig,
    RecordPlanningWindow,
    SyncTargetSnapshot,
    Pause,
    Resume,
    Delete,
    ConfirmOccurrencesSuperseded,
}

pub mod effects {
    #[allow(unused_imports)]
    use super::*;
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct EmitScheduleNotice {
        pub new_state: ScheduleLifecycleState,
        pub revision: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct SupersedePendingOccurrences {
        pub superseding_revision: u64,
        pub at_utc_ms: u64,
    }
    #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    pub struct PlanningWindowRecorded {
        pub planning_cursor_utc_ms: u64,
        pub next_occurrence_ordinal: u64,
    }
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum Effect {
    EmitScheduleNotice(effects::EmitScheduleNotice),
    SupersedePendingOccurrences(effects::SupersedePendingOccurrences),
    PlanningWindowRecorded(effects::PlanningWindowRecorded),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum EffectKind {
    EmitScheduleNotice,
    SupersedePendingOccurrences,
    PlanningWindowRecorded,
}

#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum TransitionId {
    CreateSchedule,
    ReviseActive,
    RevisePaused,
    UpdatePlanningConfigActive,
    UpdatePlanningConfigPaused,
    RecordPlanningWindowActive,
    SyncTargetSnapshotActive,
    SyncTargetSnapshotPaused,
    PauseActiveOrPaused,
    ResumeActiveOrPaused,
    DeleteActive,
    DeletePaused,
    DeleteDeleted,
    ConfirmOccurrencesSupersededActive,
    ConfirmOccurrencesSupersededPaused,
    ConfirmOccurrencesSupersededDeleted,
}
#[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::Active,
        schedule_id: ScheduleId("schedule-0".to_string()),
        revision: 1,
        trigger_key: TriggerKey("trigger-0".to_string()),
        target_binding_key: TargetBindingId("target-0".to_string()),
        misfire_policy: MisfirePolicy::Skip,
        overlap_policy: OverlapPolicy::SkipIfRunning,
        missing_target_policy: MissingTargetPolicy::MarkMisfired,
        planning_horizon_days: 30,
        planning_horizon_occurrences: 64,
        planning_cursor_utc_ms: None,
        next_occurrence_ordinal: 0,
        superseded_ack_ids: Default::default(),
    }
}
