//! D7 (security): SecretView's `Debug` impl MUST redact the inner value.
//!
//! `Zeroizing<String>` does not mask its `Debug` impl, so a stray
//! `tracing::debug!("{:?}", secret)` or `panic!("got {:?}", secret)` would
//! dump the secret to the audit channel. We provide a hand-written Debug
//! impl that emits `<REDACTED>` in place of the value; this regression
//! test pins that contract.

use cellos_core::types::SecretView;

const SENTINEL: &str = "ultra-confidential-sentinel-value-do-not-leak";

fn make_view() -> SecretView {
    SecretView {
        key: "DB_PASSWORD".to_string(),
        value: zeroize::Zeroizing::new(SENTINEL.to_string()),
    }
}

#[test]
fn debug_redacts_secret_value() {
    let view = make_view();
    let formatted = format!("{:?}", view);

    assert!(
        formatted.contains("<REDACTED>"),
        "Debug output must contain the literal `<REDACTED>` marker; got: {}",
        formatted
    );
    assert!(
        !formatted.contains(SENTINEL),
        "Debug output must NOT contain the secret value; got: {}",
        formatted
    );
}

#[test]
fn debug_pretty_redacts_secret_value() {
    // Pretty-print path (`{:#?}`) must also redact — debug_struct preserves
    // both the compact and pretty forms.
    let view = make_view();
    let formatted = format!("{:#?}", view);

    assert!(
        formatted.contains("<REDACTED>"),
        "pretty Debug must contain `<REDACTED>`; got: {}",
        formatted
    );
    assert!(
        !formatted.contains(SENTINEL),
        "pretty Debug must NOT contain the secret value; got: {}",
        formatted
    );
}

#[test]
fn debug_exposes_key_for_audit_correlation() {
    // The key (a non-secret label like `DB_PASSWORD`) is intentionally
    // visible — it's how operators correlate audit logs with broker config.
    let view = make_view();
    let formatted = format!("{:?}", view);
    assert!(
        formatted.contains("DB_PASSWORD"),
        "Debug must expose the key (kind) for audit correlation; got: {}",
        formatted
    );
}
