use thiserror::Error;

#[derive(Debug, Error)]
pub enum WalError {
    #[error("WAL schema mismatch: expected {expected}, found {found} (wipe the WAL directory)")]
    SchemaMismatch { expected: u64, found: u64 },
    #[error("corrupt WAL record at app_seq={app_seq}: {details}")]
    CorruptRecord { app_seq: u64, details: String },
    #[error("WAL sequence gap during recovery: expected seq={expected}, found seq={found}")]
    SequenceGap { expected: u64, found: u64 },
    #[error(
        "WAL recovery incomplete: need events through seq={required_through}, recovered through seq={recovered_through}"
    )]
    RecoveryIncomplete {
        required_through: u64,
        recovered_through: u64,
    },
    #[error(
        "WAL cannot continue recovery after seq={after_seq}: tx_id={tx_id} does not complete (next expected seq={next_expected_seq})"
    )]
    IncompleteTxAfterCursor {
        after_seq: u64,
        tx_id: u64,
        next_expected_seq: u64,
    },
    #[error(
        "WAL recovery cursor seq={after_seq} is beyond the recoverable head seq={recoverable_head}"
    )]
    CursorBeyondRecoverableHead {
        after_seq: u64,
        recoverable_head: u64,
    },
    #[error("invalid tx framing at app_seq={app_seq}: tx_id={tx_id} tx_len={tx_len} tx_ix={tx_ix}")]
    InvalidTxFraming {
        app_seq: u64,
        tx_id: u64,
        tx_len: u16,
        tx_ix: u16,
    },
}

#[derive(Debug, Error)]
pub enum SegmentError {
    #[error(
        "segment contiguity gap: prev_end={prev_end_seq}, next_start={next_start_seq}, expected={expected}"
    )]
    ContiguityGap {
        prev_end_seq: u64,
        next_start_seq: u64,
        expected: u64,
    },
    #[error("segment contiguity overlap: prev_end={prev_end_seq}, next_start={next_start_seq}")]
    ContiguityOverlap {
        prev_end_seq: u64,
        next_start_seq: u64,
    },
    #[error("no segments found in {path}")]
    NoSegments { path: String },
}

#[derive(Debug, Error)]
pub enum RuntimeError {
    #[error("wal thread panicked")]
    WalThreadPanic,
}
