//! Substantive happy-path test for `cellos-broker-env`.
//!
//! Scope: drives `EnvSecretBroker` through a realistic multi-secret resolve flow
//! exercised behind the `Arc<dyn SecretBroker>` trait object — this is how the
//! supervisor consumes a broker — covering:
//!
//! 1. Multi-key resolve where two secrets share a cell.
//! 2. Hyphen-normalisation (operator-friendly key form maps to underscored env).
//! 3. `revoke_for_cell` is a documented no-op for env-injected secrets.
//! 4. Re-resolve after revoke still returns the same value (the env var is the
//!    source of truth and is not torn down by `revoke_for_cell`).
//!
//! The inline unit tests cover each axis in isolation; this file proves that the
//! axes compose correctly via the public trait surface.

use std::sync::Arc;

use cellos_broker_env::EnvSecretBroker;
use cellos_core::ports::SecretBroker;

/// Use happy-path-specific env var names so this test does not race the inline
/// `#[cfg(test)]` cases or the `smoke.rs` cases which run in the same process.
const HP_KEY_A: &str = "HP_DB_PASSWORD";
const HP_KEY_A_ENV: &str = "CELLOS_SECRET_HP_DB_PASSWORD";

const HP_KEY_B_OPERATOR: &str = "hp-api-token";
const HP_KEY_B_ENV: &str = "CELLOS_SECRET_HP_API_TOKEN";

const HP_CELL: &str = "hp-cell-broker-env";

#[tokio::test]
async fn happy_path_multi_key_resolve_then_revoke_then_reresolve() {
    std::env::set_var(HP_KEY_A_ENV, "db-secret-value");
    std::env::set_var(HP_KEY_B_ENV, "api-token-value");

    let broker: Arc<dyn SecretBroker> = Arc::new(EnvSecretBroker::new());

    // (1) Multi-key resolve under the same cell, via the trait object.
    let v_a = broker
        .resolve(HP_KEY_A, HP_CELL, 60)
        .await
        .expect("happy: resolve A must succeed");
    assert_eq!(v_a.key, HP_KEY_A);
    assert_eq!(v_a.value.as_str(), "db-secret-value");

    // (2) Hyphenated operator-form key normalises to the underscored env var.
    let v_b = broker
        .resolve(HP_KEY_B_OPERATOR, HP_CELL, 60)
        .await
        .expect("happy: hyphen-normalised resolve B must succeed");
    assert_eq!(
        v_b.key, HP_KEY_B_OPERATOR,
        "broker preserves the operator-supplied key on the SecretView"
    );
    assert_eq!(v_b.value.as_str(), "api-token-value");

    // (3) revoke_for_cell is a documented no-op — must not error.
    broker
        .revoke_for_cell(HP_CELL)
        .await
        .expect("happy: env broker revoke is a no-op");

    // (4) After revoke, env-resident secrets are still resolvable: the broker
    // has no cache to drop, so the env var remains the source of truth.
    let v_a_again = broker
        .resolve(HP_KEY_A, HP_CELL, 60)
        .await
        .expect("happy: post-revoke re-resolve must still succeed");
    assert_eq!(v_a_again.value.as_str(), "db-secret-value");

    // Broker has no upstream session of its own.
    assert!(
        broker.broker_correlation_id().is_none(),
        "env broker has no broker-side correlation id"
    );

    std::env::remove_var(HP_KEY_A_ENV);
    std::env::remove_var(HP_KEY_B_ENV);
}
