#![feature(test)]
extern crate test;

use rbs::{Value, value::Table};
use rbs::value::map::ValueMap;
use serde_json;

fn create_table_data() -> Table {
    let mut table = Table::new();
    table.add_column(Value::String("id".to_string()));
    table.add_column(Value::String("name".to_string()));
    table.add_column(Value::String("email".to_string()));
    table.add_column(Value::String("phone".to_string()));
    table.add_column(Value::String("address".to_string()));
    table.add_column(Value::String("city".to_string()));
    table.add_column(Value::String("status".to_string()));
    table.add_column(Value::String("delete_flag".to_string()));
    table.add_column(Value::String("version".to_string()));
    table.add_column(Value::String("create_time".to_string()));
    table.add_column(Value::String("remark".to_string()));
    table.add_column(Value::String("sort".to_string()));

    for i in 0..1000 {
        table.add_row(vec![
            Value::U64(i),
            Value::String(format!("name_{}", i)),
            Value::String(format!("user{}@example.com", i)),
            Value::String(format!("13800138{:04}", i)),
            Value::String(format!("Address Street {}, City", i)),
            Value::String(format!("City_{}", i % 100)),
            Value::String("1".to_string()),
            Value::String("1".to_string()),
            Value::String("1".to_string()),
            Value::String("2025-12-29T12:10:38".to_string()),
            Value::String("remark".to_string()),
            Value::String("1".to_string()),
        ]);
    }
    table
}

fn create_traditional_data() -> Vec<Value> {
    let mut traditional = Vec::with_capacity(1000);
    for i in 0..1000 {
        let mut map = ValueMap::new();
        map.insert(Value::String("id".to_string()), Value::U64(i));
        map.insert(Value::String("name".to_string()), Value::String(format!("name_{}", i)));
        map.insert(Value::String("email".to_string()), Value::String(format!("user{}@example.com", i)));
        map.insert(Value::String("phone".to_string()), Value::String(format!("13800138{:04}", i)));
        map.insert(Value::String("address".to_string()), Value::String(format!("Address Street {}, City", i)));
        map.insert(Value::String("city".to_string()), Value::String(format!("City_{}", i % 100)));
        map.insert(Value::String("status".to_string()), Value::String("1".to_string()));
        map.insert(Value::String("delete_flag".to_string()), Value::String("1".to_string()));
        map.insert(Value::String("version".to_string()), Value::String("1".to_string()));
        map.insert(Value::String("create_time".to_string()), Value::String("2025-12-29T12:10:38".to_string()));
        map.insert(Value::String("remark".to_string()), Value::String("remark".to_string()));
        map.insert(Value::String("sort".to_string()), Value::String("1".to_string()));
        traditional.push(Value::Map(map));
    }
    traditional
}

#[bench]
fn bench_table_serialize(b: &mut test::Bencher) {
    let table = create_table_data();
    let value = Value::Table(table);
    b.iter(|| {
        let _ = serde_json::to_string(&value).unwrap();
    });
}

#[bench]
fn bench_table_deserialize(b: &mut test::Bencher) {
    let table = create_table_data();
    let value = Value::Table(table);
    let json = serde_json::to_string(&value).unwrap();
    b.iter(|| {
        let _: Value = serde_json::from_str(&json).unwrap();
    });
}

#[bench]
fn bench_traditional_serialize(b: &mut test::Bencher) {
    let traditional = create_traditional_data();
    b.iter(|| {
        let _ = serde_json::to_string(&traditional).unwrap();
    });
}

#[bench]
fn bench_traditional_deserialize(b: &mut test::Bencher) {
    let traditional = create_traditional_data();
    let json = serde_json::to_string(&traditional).unwrap();
    b.iter(|| {
        let _: Vec<Value> = serde_json::from_str(&json).unwrap();
    });
}

// This function runs once to show size comparison
fn print_size_comparison() {
    let table = create_table_data();
    let traditional = create_traditional_data();

    let table_json = serde_json::to_string(&Value::Table(table)).unwrap();
    let traditional_json = serde_json::to_string(&traditional).unwrap();

    let table_size = table_json.len();
    let traditional_size = traditional_json.len();
    let reduction = ((traditional_size - table_size) as f64 / traditional_size as f64) * 100.0;

    println!("\n===========================================");
    println!("      列式存储 vs 传统格式对比 (1000条 × 12字段)");
    println!("===========================================");
    println!("传统格式 (Vec<ValueMap>): {:>7} 字节", traditional_size);
    println!("列式存储 (Table):         {:>7} 字节", table_size);
    println!("压缩率:                  {:>5.1}%", reduction);
    println!("===========================================\n");
}

// Run the size comparison once at startup
#[ctor::ctor]
fn on_start() {
    print_size_comparison();
}
