use criterion::{Criterion, criterion_group, criterion_main};
use trueskill_tt::{
    BETA, Competitor, ConvergenceOptions, EventKind, GAMMA, KeyTable, MU, P_DRAW, Rating, SIGMA,
    TimeSlice, drift::ConstantDrift, gaussian::Gaussian, storage::CompetitorStore,
};

fn criterion_benchmark(criterion: &mut Criterion) {
    let mut index_map = KeyTable::new();

    let a = index_map.get_or_create("a");
    let b = index_map.get_or_create("b");
    let c = index_map.get_or_create("c");

    let mut agents: CompetitorStore<i64, ConstantDrift> = CompetitorStore::new();

    for agent in [a, b, c] {
        agents.insert(
            agent,
            Competitor {
                rating: Rating::new(Gaussian::from_ms(MU, SIGMA), BETA, ConstantDrift(GAMMA)),
                ..Default::default()
            },
        );
    }

    let mut composition = Vec::new();
    let mut results = Vec::new();
    let mut weights = Vec::new();

    for _ in 0..100 {
        composition.push(vec![vec![a], vec![b]]);
        results.push(vec![1.0, 0.0]);
        weights.push(vec![vec![1.0], vec![1.0]]);
    }

    let kinds = vec![EventKind::Ranked; composition.len()];

    let mut time_slice = TimeSlice::new(1, P_DRAW, ConvergenceOptions::default());
    time_slice.add_events(composition, results, weights, kinds, &agents);

    criterion.bench_function("Batch::iteration", |b| {
        b.iter(|| time_slice.iteration(0, &agents))
    });
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
