//! Hybrid search (RRF) profiling: text+kNN combined, fusion overhead.

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

use std::time::Instant;

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

#[test]
fn rrf_fusion_overhead() {
    println!("\n=== Hybrid: RRF Fusion Overhead (5K docs, 64d) ===\n");

    let (path, mut index) = build_vector_corpus("hybrid_rrf", 5_000, 64);

    let query_vec: Vec<f64> = (0..64).map(|i| (i as f64 / 64.0) * 2.0 - 1.0).collect();

    print_measurement_header();

    // Text-only
    let m = measure_query("text_only", &mut index, json!({"match": {"title": "vector doc"}}), 10, WARMUP, ITERS);
    print_measurement(&m);

    // kNN-only
    let m = measure_query("knn_only", &mut index, json!({
        "knn": {"field": "embedding", "query_vector": &query_vec, "k": 10, "num_candidates": 50},
        "size": 10
    }), 10, WARMUP, ITERS);
    print_measurement(&m);

    // Hybrid (text + kNN + RRF)
    let m = measure_query("hybrid_rrf", &mut index, json!({
        "query": {"match": {"title": "vector doc"}},
        "knn": {"field": "embedding", "query_vector": &query_vec, "k": 10, "num_candidates": 50},
        "size": 10
    }), 10, WARMUP, ITERS);
    print_measurement(&m);

    // Hybrid with aggs
    let m = measure_query("hybrid_rrf+aggs", &mut index, json!({
        "query": {"match": {"title": "vector doc"}},
        "knn": {"field": "embedding", "query_vector": &query_vec, "k": 10, "num_candidates": 50},
        "aggs": {"by_tag": {"terms": {"field": "tag"}}},
        "size": 10
    }), 10, WARMUP, ITERS);
    print_measurement(&m);
    // Hybrid RRF with aggs should be under 25ms p99 on 5K docs
    m.assert_p99_under_ms(25);

    cleanup(&path);
}

#[test]
fn rrf_scaling_by_k() {
    println!("\n=== Hybrid: RRF Scaling by k (5K docs, 64d) ===\n");

    let (path, mut index) = build_vector_corpus("hybrid_k", 5_000, 64);
    let query_vec: Vec<f64> = (0..64).map(|i| (i as f64 / 64.0) * 2.0 - 1.0).collect();

    print_measurement_header();
    for &k in &[5, 10, 50, 100] {
        let m = measure_query(
            &format!("hybrid k={k}"),
            &mut index,
            json!({
                "query": {"match": {"title": "vector"}},
                "knn": {"field": "embedding", "query_vector": &query_vec, "k": k, "num_candidates": k * 2},
                "size": k
            }),
            k, WARMUP, ITERS,
        );
        print_measurement(&m);
    }
    cleanup(&path);
}
