//! Aggregation performance profiling.

use super::harness::*;
use serde_json::json;

const WARMUP: usize = 3;
const ITERS: usize = 20;

#[test]
fn metric_aggs() {
    println!("\n=== Aggregations: Metrics (50K docs) ===\n");

    let (path, mut index) = build_text_corpus("agg_metric", 50_000);

    print_measurement_header();
    let queries: Vec<(&str, serde_json::Value)> = vec![
        ("avg", json!({"query": {"match_all": {}}, "aggs": {"x": {"avg": {"field": "price"}}}, "size": 0})),
        ("sum", json!({"query": {"match_all": {}}, "aggs": {"x": {"sum": {"field": "price"}}}, "size": 0})),
        ("min", json!({"query": {"match_all": {}}, "aggs": {"x": {"min": {"field": "price"}}}, "size": 0})),
        ("max", json!({"query": {"match_all": {}}, "aggs": {"x": {"max": {"field": "price"}}}, "size": 0})),
        ("value_count", json!({"query": {"match_all": {}}, "aggs": {"x": {"value_count": {"field": "price"}}}, "size": 0})),
        ("stats", json!({"query": {"match_all": {}}, "aggs": {"x": {"stats": {"field": "price"}}}, "size": 0})),
    ];

    for (name, query) in &queries {
        let m = measure_query(name, &mut index, query.clone(), 0, WARMUP, ITERS);
        print_measurement(&m);
        // All metric aggs should complete in under 50ms p99 on 50K docs
        m.assert_p99_under_ms(50);
    }
    cleanup(&path);
}

#[test]
fn bucket_aggs() {
    println!("\n=== Aggregations: Buckets (50K docs) ===\n");

    let (path, mut index) = build_text_corpus("agg_bucket", 50_000);

    print_measurement_header();
    let queries: Vec<(&str, serde_json::Value)> = vec![
        ("terms_5unique", json!({"query": {"match_all": {}}, "aggs": {"x": {"terms": {"field": "tag"}}}, "size": 0})),
        ("histogram_10", json!({"query": {"match_all": {}}, "aggs": {"x": {"histogram": {"field": "price", "interval": 10.0}}}, "size": 0})),
        ("histogram_1", json!({"query": {"match_all": {}}, "aggs": {"x": {"histogram": {"field": "price", "interval": 1.0}}}, "size": 0})),
        ("range_3buckets", json!({"query": {"match_all": {}}, "aggs": {"x": {"range": {"field": "price", "ranges": [
            {"to": 25.0}, {"from": 25.0, "to": 75.0}, {"from": 75.0}
        ]}}}, "size": 0})),
    ];

    for (name, query) in &queries {
        let m = measure_query(name, &mut index, query.clone(), 0, WARMUP, ITERS);
        print_measurement(&m);
        // Bucket aggs should complete in under 100ms p99 on 50K docs
        m.assert_p99_under_ms(100);
    }
    cleanup(&path);
}

#[test]
fn nested_sub_aggs() {
    println!("\n=== Aggregations: Nested Sub-Aggs (50K docs) ===\n");

    let (path, mut index) = build_text_corpus("agg_nested", 50_000);

    print_measurement_header();
    let queries: Vec<(&str, serde_json::Value)> = vec![
        ("terms→avg", json!({"query": {"match_all": {}}, "aggs": {"x": {
            "terms": {"field": "tag"},
            "aggs": {"y": {"avg": {"field": "price"}}}
        }}, "size": 0})),
        ("terms→stats", json!({"query": {"match_all": {}}, "aggs": {"x": {
            "terms": {"field": "tag"},
            "aggs": {"y": {"stats": {"field": "price"}}}
        }}, "size": 0})),
        ("terms→terms(SKIP)", json!({"match_all": {}})), // placeholder — needs 2nd keyword field
    ];

    for (name, query) in &queries {
        if name.contains("SKIP") { continue; }
        let m = measure_query(name, &mut index, query.clone(), 0, WARMUP, ITERS);
        print_measurement(&m);
    }
    cleanup(&path);
}

#[test]
fn high_cardinality_terms() {
    println!("\n=== Aggregations: High Cardinality Terms ===\n");

    print_measurement_header();
    for &cardinality in &[10, 100, 1_000, 10_000] {
        let label = format!("terms_{cardinality}unique");
        let (path, mut index) = build_high_cardinality_corpus(&label, 50_000, cardinality);

        let m = measure_query(
            &format!("terms ({cardinality} unique)"),
            &mut index,
            json!({"query": {"match_all": {}}, "aggs": {"x": {"terms": {"field": "category", "size": 100}}}, "size": 0}),
            0, WARMUP, ITERS,
        );
        print_measurement(&m);
        cleanup(&path);
    }
}
