//! Tests for policy source tracking in conflicts.

use crate::*;

#[tokio::test]
async fn test_policy_source_info_in_conflict() {
    // Test that PolicySourceInfo is correctly populated when conflicts come from Trust Packs

    let temp_dir = tempfile::Builder::new()
        .prefix("aphoria_policy_source")
        .tempdir()
        .expect("create temp dir");

    // Create .aphoria directory for the agent key
    let aphoria_dir = temp_dir.path().join(".aphoria");
    std::fs::create_dir_all(&aphoria_dir).expect("create .aphoria dir");

    // Create a Trust Pack with a TLS assertion that will conflict with our test code
    let signing_key = crate::bridge::load_or_generate_key(temp_dir.path()).expect("load key");

    // Create assertion using bridge helper
    let tls_claim = ExtractedClaim {
        concept_path: "rfc://custom/tls/cert_verification".to_string(),
        predicate: "enabled".to_string(),
        value: stemedb_core::types::ObjectValue::Boolean(true),
        file: "policy".to_string(),
        line: 0,
        matched_text: "TLS required".to_string(),
        confidence: 1.0,
        description: "TLS must be enabled".to_string(),
    };

    let timestamp = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .map(|d| d.as_secs())
        .unwrap_or(0);
    let tls_assertion = crate::bridge::claim_to_assertion(&tls_claim, &signing_key, timestamp);

    let pack = crate::policy::TrustPack::new(
        "Test Policy Pack".to_string(),
        "2.0.0".to_string(),
        vec![tls_assertion],
        vec![],
        &signing_key,
    )
    .expect("create pack");

    // Save the pack
    let pack_path = temp_dir.path().join("test.pack");
    pack.save(&pack_path).expect("save pack");

    // Create EphemeralDetector and ingest the policy
    let corpus_config = crate::CorpusConfig::default();
    let mut detector = crate::episteme::EphemeralDetector::new(&signing_key, &corpus_config);

    let loaded_pack = crate::policy::TrustPack::load(&pack_path).expect("load pack");
    detector.ingest_policies(&[loaded_pack]);

    // Verify pack source is tracked
    let source_info = detector.get_pack_source("rfc://custom/tls/cert_verification");
    assert!(source_info.is_some(), "Pack source should be tracked");

    let info = source_info.expect("source info");
    assert_eq!(info.pack_name, "Test Policy Pack");
    assert_eq!(info.pack_version, "2.0.0");
    assert_eq!(info.issuer_hex.len(), 8, "Issuer hex should be 8 chars (4 bytes)");
}

#[tokio::test]
async fn test_persistent_mode_policy_source_tracking() {
    // Test that policy source is stored and retrieved in persistent mode
    // via import_policy → LocalEpisteme.pack_source_store

    use stemedb_storage::PackSourceStore;

    let temp_dir = tempfile::Builder::new()
        .prefix("aphoria_persistent_policy_source")
        .tempdir()
        .expect("create temp dir");

    // Create .aphoria directory for the agent key
    let aphoria_dir = temp_dir.path().join(".aphoria");
    std::fs::create_dir_all(&aphoria_dir).expect("create .aphoria dir");

    // Create a Trust Pack
    let signing_key = crate::bridge::load_or_generate_key(temp_dir.path()).expect("load key");
    let timestamp = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .map(|d| d.as_secs())
        .unwrap_or(0);

    // Create assertion using bridge helper
    let policy_claim = ExtractedClaim {
        concept_path: "rfc://persistent/test/policy".to_string(),
        predicate: "enabled".to_string(),
        value: stemedb_core::types::ObjectValue::Boolean(true),
        file: "policy".to_string(),
        line: 0,
        matched_text: "Policy enabled".to_string(),
        confidence: 1.0,
        description: "Test policy assertion".to_string(),
    };

    let policy_assertion =
        crate::bridge::claim_to_assertion(&policy_claim, &signing_key, timestamp);

    let pack = crate::policy::TrustPack::new(
        "Persistent Test Pack".to_string(),
        "3.0.0".to_string(),
        vec![policy_assertion],
        vec![],
        &signing_key,
    )
    .expect("create pack");

    // Save the pack
    let pack_path = temp_dir.path().join("persistent_test.pack");
    pack.save(&pack_path).expect("save pack");

    // Set up config for import
    let mut config = AphoriaConfig::default();
    config.episteme.data_dir = temp_dir.path().join(".aphoria").join("db");

    // Import the policy
    let import_stats =
        crate::policy_ops::import_policy(pack_path.clone(), &config).await.expect("import policy");

    assert_eq!(import_stats.assertions_imported, 1, "Should import 1 assertion");

    // Now open LocalEpisteme and verify pack source is stored
    let episteme =
        crate::episteme::LocalEpisteme::open(&config, temp_dir.path()).await.expect("open");

    // Look up pack source via the store
    let pack_source = episteme
        .pack_source_store()
        .get_pack_source("rfc://persistent/test/policy")
        .await
        .expect("get pack source");

    assert!(pack_source.is_some(), "Pack source should be stored after import");

    let info = pack_source.expect("pack source info");
    assert_eq!(info.pack_name, "Persistent Test Pack");
    assert_eq!(info.pack_version, "3.0.0");
    assert_eq!(info.issuer_hex.len(), 8, "Issuer hex should be 8 chars (4 bytes)");
}
