//! Indexing throughput and memory profiling.

use super::harness::*;
use luci_index::index::Index;
use serde_json::json;
use std::time::Instant;

#[test]
fn throughput_scaling() {
    println!("\n=== Indexing Throughput ===\n");

    for &count in &[1_000, 5_000, 10_000, 50_000] {
        let path = profile_dir(&format!("idx_tp_{count}"));
        let mem_before = memory_usage_kb();

        let start = Instant::now();
        let mut index = Index::create_with_mapping(&path, text_schema()).unwrap();
        let tags = ["tech", "science", "sports", "politics", "entertainment"];
        for i in 0..count {
            let tag = tags[i % tags.len()];
            index.add(json!({
                "title": format!("document number {i} about {tag} topics"),
                "body": format!("this is the body text for document {i} covering {tag} related content"),
                "tag": tag,
                "price": (i as f64 % 100.0) + 0.99,
            })).unwrap();
        }
        let add_elapsed = start.elapsed();
        let commit_start = Instant::now();
        index.commit().unwrap();
        let commit_elapsed = commit_start.elapsed();
        let total = start.elapsed();
        let mem_after = memory_usage_kb();
        let mem_delta = mem_after.saturating_sub(mem_before);

        println!("{count:>6} docs: add={:.0}ms commit={:.0}ms total={:.0}ms ({:.0} docs/s) mem={mem_delta}KB",
            add_elapsed.as_millis(), commit_elapsed.as_millis(),
            total.as_millis(), count as f64 / total.as_secs_f64());

        cleanup(&path);
    }
}

#[test]
fn memory_per_doc() {
    println!("\n=== Memory Per Document ===\n");

    let path = profile_dir("mem_per_doc");
    let mem_before = memory_usage_kb();
    let mut index = Index::create_with_mapping(&path, text_schema()).unwrap();
    let tags = ["a", "b", "c", "d", "e"];

    for i in 0..50_000usize {
        index.add(json!({
            "title": format!("document {i}"),
            "body": format!("body text for document {i} with some more words"),
            "tag": tags[i % tags.len()],
            "price": (i as f64 % 100.0),
        })).unwrap();

        if [1_000, 5_000, 10_000, 25_000, 50_000].contains(&(i + 1)) {
            index.commit().unwrap();
            let mem_now = memory_usage_kb();
            let delta = mem_now.saturating_sub(mem_before);
            let per_doc = delta as f64 / (i + 1) as f64;
            println!("{:>6} docs: RSS={mem_now}KB  delta={delta}KB  ({per_doc:.1}KB/doc)", i + 1);
        }
    }

    let disk = disk_usage_bytes(&path);
    println!("\nDisk: {:.1}MB total, {:.0} bytes/doc", disk as f64 / 1_048_576.0, disk as f64 / 50_000.0);
    cleanup(&path);
}
