//! Property-based round-trip tests for IMAP Flag.
//!
//! Uses `proptest` to verify that encoding a Flag to its wire form
//! and parsing it back yields an equal flag.
//!
//! # References
//! - RFC 3501 Section 2.3.2 (message flags)
//! - RFC 9051 Section 2.3.2 (`IMAP4rev2` flags)

use daaki_imap::types::Flag;
use proptest::prelude::*;

/// Generates a Flag value (RFC 3501 Section 2.3.2).
///
/// Covers all seven standard variants plus randomly generated custom
/// keyword flags. Custom flags use the pattern `$[A-Za-z][A-Za-z0-9_]*`
/// which produces valid IMAP atoms that do not collide with system flags.
fn arb_flag() -> impl Strategy<Value = Flag> {
    prop_oneof![
        2 => Just(Flag::Seen),
        2 => Just(Flag::Answered),
        2 => Just(Flag::Flagged),
        2 => Just(Flag::Deleted),
        2 => Just(Flag::Draft),
        1 => Just(Flag::Recent),
        1 => Just(Flag::Wildcard),
        3 => "\\$[A-Za-z][A-Za-z0-9_]{0,20}".prop_map(Flag::Custom),
    ]
}

proptest! {
    /// Flag as_imap_str -> from_imap_str round-trip
    /// (RFC 3501 Section 2.3.2, RFC 9051 Section 2.3.2).
    ///
    /// For any Flag, encoding it to its wire representation and parsing
    /// it back must yield an equal flag.
    #[test]
    fn flag_roundtrip(flag in arb_flag()) {
        let wire = flag.as_imap_str().to_string();
        let back = Flag::from_imap_str(&wire);
        prop_assert_eq!(flag, back, "round-trip failed for wire={:?}", wire);
    }
}
