use proptest::test_runner::{Config as ProptestConfig, FileFailurePersistence};

/// Named test profiles. Select via `PROPTEST_PROFILE` env var.
///
/// ```
/// PROPTEST_PROFILE=thorough cargo nextest run --test proptest_parser
/// PROPTEST_PROFILE=ci       cargo nextest run --test proptest_parser
/// PROPTEST_PROFILE=quick    cargo nextest run --test proptest_parser
/// ```
#[derive(Debug, Clone, Copy)]
pub enum Profile {
    /// 32 cases — fast feedback during active development.
    Quick,
    /// 256 cases — default for local runs.
    Default,
    /// 2048 cases — deeper coverage before merging.
    Thorough,
    /// 512 cases, no failure persistence — reproducible CI runs.
    Ci,
}

impl Profile {
    pub fn from_env() -> Self {
        match std::env::var("PROPTEST_PROFILE")
            .unwrap_or_default()
            .to_ascii_lowercase()
            .as_str()
        {
            "quick" => Self::Quick,
            "thorough" => Self::Thorough,
            "ci" => Self::Ci,
            _ => Self::Default,
        }
    }

    pub fn cases(self) -> u32 {
        match self {
            Self::Quick => 32,
            Self::Default => 256,
            Self::Thorough => 2048,
            Self::Ci => 512,
        }
    }

    pub fn max_shrink_iters(self) -> u32 {
        match self {
            Self::Quick => 128,
            Self::Default => 512,
            Self::Thorough => 2048,
            Self::Ci => 512,
        }
    }
}

/// Build a `ProptestConfig` for the current `PROPTEST_PROFILE`.
///
/// `PROPTEST_CASES` still overrides the case count (proptest's own env var).
pub fn config() -> ProptestConfig {
    let profile = Profile::from_env();

    // Honour proptest's own PROPTEST_CASES override on top of the profile default.
    let cases = std::env::var("PROPTEST_CASES")
        .ok()
        .and_then(|s| s.parse().ok())
        .unwrap_or_else(|| profile.cases());

    let persistence: Option<Box<dyn proptest::test_runner::FailurePersistence>> =
        match profile {
            Profile::Ci => None, // no filesystem state in CI
            _ => Some(Box::new(FileFailurePersistence::WithSource(
                "proptest-regressions",
            ))),
        };

    ProptestConfig {
        cases,
        max_shrink_iters: profile.max_shrink_iters(),
        failure_persistence: persistence,
        ..ProptestConfig::default()
    }
}
