#![cfg(feature = "test-utils")]

use std::sync::Arc;

use dirigent_archivist::backend::mock::MockBackend;
use dirigent_archivist::backend::{ArchiveBackend, ArchiveCapability, CapabilitySet, HealthStatus};
use dirigent_archivist::coordinator::Archivist;
use dirigent_archivist::registry::{ArchiveRegistration, FailureMode, WritePolicy};
use dirigent_archivist::types::{MetaEventRecord, MetaEventType};
use uuid::Uuid;

fn reg(name: &str, backend: Arc<MockBackend>, priority: u32) -> Arc<ArchiveRegistration> {
    Arc::new(ArchiveRegistration::new(
        name.into(),
        "mock",
        backend as Arc<dyn ArchiveBackend>,
        true,
        FailureMode::Required,
        priority,
        true,
        WritePolicy::Inline,
        None,
        HealthStatus::Healthy,
    ))
}

fn stub_meta_event(scroll_id: Uuid) -> MetaEventRecord {
    MetaEventRecord {
        version: 1,
        event_id: Uuid::now_v7(),
        session: scroll_id,
        ts: chrono::Utc::now(),
        event_type: MetaEventType::ClientConnected,
        description: "test event".into(),
        linked_session_id: None,
        linked_connector_id: None,
        linked_connector_title: None,
        metadata: serde_json::Value::Null,
    }
}

#[tokio::test]
async fn capability_filter_skips_backend_without_meta_events() {
    let mut caps_with_meta = CapabilitySet::new();
    caps_with_meta.insert(ArchiveCapability::MetaEvents);
    caps_with_meta.insert(ArchiveCapability::SessionMapping);
    caps_with_meta.insert(ArchiveCapability::ConnectorRegistry);
    let with_meta = Arc::new(MockBackend::with_capabilities(caps_with_meta));

    let mut caps_without_meta = CapabilitySet::new();
    caps_without_meta.insert(ArchiveCapability::SessionMapping);
    caps_without_meta.insert(ArchiveCapability::ConnectorRegistry);
    let without_meta = Arc::new(MockBackend::with_capabilities(caps_without_meta));

    let archivist = Archivist::from_registrations(vec![
        reg("primary", with_meta.clone(), 0),
        reg("secondary", without_meta.clone(), 10),
    ]);

    let scroll = Uuid::new_v4();
    archivist
        .append_meta_events(scroll, vec![stub_meta_event(scroll)], None)
        .await
        .unwrap();

    // Primary received the meta event.
    assert!(
        with_meta.has_meta_events(scroll),
        "primary should receive meta event"
    );
    // Secondary was capability-skipped.
    assert!(
        !without_meta.has_meta_events(scroll),
        "secondary should be skipped"
    );
}
