//! Integration smoke test for `cellos-host-cellos`.
//!
//! Scope: smoke wires only — exercises `ProprietaryCellBackend` create/destroy
//! plus the in-memory `MemorySecretBroker` resolve+revoke contract through the
//! public `CellBackend` and `SecretBroker` traits.

use cellos_core::ports::{CellBackend, SecretBroker};
use cellos_core::ExecutionCellDocument;
use cellos_host_cellos::{MemorySecretBroker, ProprietaryCellBackend};

fn smoke_doc(id: &str) -> ExecutionCellDocument {
    serde_json::from_value(serde_json::json!({
        "apiVersion": "cellos.io/v1",
        "kind": "ExecutionCell",
        "spec": {
            "id": id,
            "authority": { "secretRefs": [] },
            "lifetime": { "ttlSeconds": 60 }
        }
    }))
    .expect("smoke: sample spec must parse")
}

#[tokio::test]
async fn smoke_backend_create_and_destroy_round_trip() {
    let host = ProprietaryCellBackend::new();
    let doc = smoke_doc("smoke-cell-1");

    let handle = host.create(&doc).await.expect("smoke: create must succeed");
    assert_eq!(handle.cell_id, "smoke-cell-1");
    assert_eq!(host.tracked_cell_count().await, 1);

    let report = host
        .destroy(&handle)
        .await
        .expect("smoke: destroy must succeed");
    assert!(report.destroyed);
    assert_eq!(report.peers_tracked_after, 0);
    assert!(!host.has_tracked_state("smoke-cell-1").await);
}

#[tokio::test]
async fn smoke_backend_destroy_unknown_errors() {
    let host = ProprietaryCellBackend::default();
    // Synthesize a handle for an id the host has never seen.
    let handle = cellos_core::ports::CellHandle {
        cell_id: "smoke-never-created".into(),
        cgroup_path: None,
        nft_rules_applied: None,
        kernel_digest_sha256: None,
        rootfs_digest_sha256: None,
        firecracker_digest_sha256: None,
    };
    let err = host
        .destroy(&handle)
        .await
        .expect_err("smoke: destroying unknown cell must error");
    assert!(
        err.to_string().contains("smoke-never-created"),
        "error should mention the cell id, got: {err}"
    );
}

#[tokio::test]
async fn smoke_memory_broker_resolve_and_revoke() {
    let broker = MemorySecretBroker::new();
    let view = broker
        .resolve("SMOKE_KEY", "smoke-cell-2", 60)
        .await
        .expect("smoke: resolve must succeed");
    assert_eq!(view.key, "SMOKE_KEY");
    assert!(view.value.as_str().contains("smoke-cell-2"));
    assert_eq!(
        broker
            .materialized_keys_for_cell("smoke-cell-2")
            .await
            .len(),
        1
    );

    broker
        .revoke_for_cell("smoke-cell-2")
        .await
        .expect("smoke: revoke_for_cell must succeed");
    assert!(broker
        .materialized_keys_for_cell("smoke-cell-2")
        .await
        .is_empty());
}
