//! Database integration tests

use gdelt::db::duckdb::{AnalyticsDb, EventFilters};
use gdelt::db::cache::CacheDb;

#[test]
fn test_analytics_db_open_memory() {
    let db = AnalyticsDb::open_memory();
    assert!(db.is_ok(), "Failed to open in-memory analytics database");
}

#[test]
fn test_cache_db_open_memory() {
    let db = CacheDb::open_memory();
    assert!(db.is_ok(), "Failed to open in-memory cache database");
}

#[test]
fn test_db_stats_empty() {
    let db = AnalyticsDb::open_memory().unwrap();
    let stats = db.stats();
    assert!(stats.is_ok(), "Failed to get stats");

    let stats = stats.unwrap();
    assert_eq!(stats.events_count, 0);
    assert_eq!(stats.gkg_count, 0);
    assert_eq!(stats.mentions_count, 0);
}

#[test]
fn test_query_empty_events() {
    let db = AnalyticsDb::open_memory().unwrap();
    let filters = EventFilters::default();
    let events = db.query_events(filters);
    assert!(events.is_ok(), "Failed to query events");
    assert_eq!(events.unwrap().len(), 0);
}

#[test]
fn test_query_with_filters() {
    let db = AnalyticsDb::open_memory().unwrap();
    let filters = EventFilters {
        actor: Some("USA".to_string()),
        country: Some("US".to_string()),
        limit: 10,
        offset: 0,
        ..Default::default()
    };
    let events = db.query_events(filters);
    assert!(events.is_ok(), "Failed to query events with filters");
}

#[test]
fn test_raw_query() {
    let db = AnalyticsDb::open_memory().unwrap();
    let result = db.query("SELECT COUNT(*) as cnt FROM events");
    assert!(result.is_ok(), "Failed to run raw query");

    let result = result.unwrap();
    // Verify we got results
    assert!(!result.columns.is_empty(), "Should have columns");
}

#[test]
fn test_lookup_nonexistent_event() {
    let db = AnalyticsDb::open_memory().unwrap();
    let event = db.lookup_event(999999999);
    assert!(event.is_ok());
    assert!(event.unwrap().is_none(), "Should not find nonexistent event");
}

#[test]
fn test_cache_db_get_set_setting() {
    let db = CacheDb::open_memory().unwrap();

    // Set a setting
    let result = db.set_setting("test_key", "test_value");
    assert!(result.is_ok(), "Failed to set setting");

    // Get the setting
    let value = db.get_setting("test_key");
    assert!(value.is_ok());
    assert_eq!(value.unwrap(), Some("test_value".to_string()));
}

#[test]
fn test_cache_db_get_nonexistent_setting() {
    let db = CacheDb::open_memory().unwrap();
    let value = db.get_setting("nonexistent_key");
    assert!(value.is_ok());
    assert!(value.unwrap().is_none());
}

#[test]
fn test_cache_db_api_cache() {
    let db = CacheDb::open_memory().unwrap();

    // Put a cached response
    let result = db.put_cached(
        "https://example.com/api",
        r#"{"result": "test"}"#,
        Some("application/json"),
        3600,
    );
    assert!(result.is_ok(), "Failed to cache response");

    // Get the cached response
    let cached = db.get_cached("https://example.com/api");
    assert!(cached.is_ok());
    let cached = cached.unwrap();
    assert!(cached.is_some(), "Should find cached response");
    assert_eq!(cached.unwrap().body, r#"{"result": "test"}"#);
}

#[test]
fn test_cache_db_prune_expired() {
    let db = CacheDb::open_memory().unwrap();
    let pruned = db.prune_expired();
    assert!(pruned.is_ok(), "Failed to prune expired entries");
}

#[test]
fn test_cache_db_clear() {
    let db = CacheDb::open_memory().unwrap();

    // Add some data
    let _ = db.set_setting("key", "value");
    let _ = db.put_cached("https://test.com", "{}", None, 3600);

    // Clear the cache
    let result = db.clear();
    assert!(result.is_ok(), "Failed to clear cache");

    // Verify it's cleared
    let stats = db.stats().unwrap();
    assert_eq!(stats.api_cache_entries, 0);
}

#[test]
fn test_cache_db_stats() {
    let db = CacheDb::open_memory().unwrap();
    let stats = db.stats();
    assert!(stats.is_ok(), "Failed to get cache stats");
}
