//! TypeState markers for proof lifecycle.
//!
//! These zero-sized types encode proof state at the type level,
//! enabling compile-time enforcement of valid state transitions.

use std::fmt::Debug;

/// Sealed trait pattern to prevent external implementations.
mod sealed {
    pub trait Sealed {}
}

/// Marker trait for proof states.
///
/// This trait is sealed - only the states defined in this module
/// can implement it, ensuring a closed set of valid states.
pub trait ProofState: sealed::Sealed + Clone + Debug + Default {}

/// Proof has been created but not yet verified.
///
/// A proof in this state cannot be submitted for aggregation.
#[derive(Clone, Debug, Default)]
pub struct Pending;

/// Proof has been verified against its verification key.
///
/// Only verified proofs can be submitted for aggregation.
#[derive(Clone, Debug, Default)]
pub struct Verified;

/// Proof has been submitted to the aggregation queue.
///
/// Batched proofs are waiting to be aggregated.
#[derive(Clone, Debug, Default)]
pub struct Batched;

/// Final aggregated proof combining multiple proofs.
///
/// This state represents the output of the aggregation process.
#[derive(Clone, Debug, Default)]
pub struct Aggregated;

// Implement sealed trait for all states
impl sealed::Sealed for Pending {}
impl sealed::Sealed for Verified {}
impl sealed::Sealed for Batched {}
impl sealed::Sealed for Aggregated {}

// Implement ProofState for all states
impl ProofState for Pending {}
impl ProofState for Verified {}
impl ProofState for Batched {}
impl ProofState for Aggregated {}

#[cfg(test)]
mod tests {
    use super::*;

    // TDD: These tests verify TypeState properties

    #[test]
    fn states_are_zero_sized() {
        assert_eq!(std::mem::size_of::<Pending>(), 0);
        assert_eq!(std::mem::size_of::<Verified>(), 0);
        assert_eq!(std::mem::size_of::<Batched>(), 0);
        assert_eq!(std::mem::size_of::<Aggregated>(), 0);
    }

    #[test]
    fn states_implement_required_traits() {
        // Clone
        let p = Pending;
        let _p2 = p.clone();

        // Debug
        let v = Verified;
        let _ = format!("{:?}", v);

        // Default
        let _b: Batched = Default::default();
    }

    #[test]
    fn states_are_distinct_types() {
        // This is a compile-time check
        fn takes_pending(_: Pending) {}
        fn takes_verified(_: Verified) {}

        takes_pending(Pending);
        takes_verified(Verified);

        // The following would fail to compile (good!):
        // takes_pending(Verified);
    }
}
