use criterion::{Criterion, criterion_group, criterion_main};
use trueskill_tt::gaussian::Gaussian;

fn benchmark_gaussian_arithmetic(criterion: &mut Criterion) {
    // Define test Gaussians
    let g1 = Gaussian::from_ms(25.0, 25.0 / 3.0);
    let g2 = Gaussian::from_ms(0.0, 1.0);
    let g3 = Gaussian::from_ms(1.0, 1.0);

    // Benchmark addition
    criterion.bench_function("Gaussian::add", |bencher| {
        bencher.iter(|| g1 + g2);
    });

    // Benchmark subtraction
    criterion.bench_function("Gaussian::sub", |bencher| {
        bencher.iter(|| g1 - g3);
    });

    // Benchmark multiplication
    criterion.bench_function("Gaussian::mul", |bencher| {
        bencher.iter(|| g1 * g2);
    });

    // Benchmark division
    // NOTE: numerator must have higher precision (smaller sigma) than the
    // denominator in this representation; g2 (sigma=1) / g1 (sigma=8.33) is
    // well-defined, whereas g1 / g2 underflows and panics in mu_sigma.
    criterion.bench_function("Gaussian::div", |bencher| {
        bencher.iter(|| g2 / g1);
    });

    // Benchmark natural parameter conversions
    criterion.bench_function("Gaussian::pi", |bencher| {
        bencher.iter(|| g1.pi());
    });

    criterion.bench_function("Gaussian::tau", |bencher| {
        bencher.iter(|| g1.tau());
    });

    // Benchmark combined pi/tau operations (used in mul/div)
    criterion.bench_function("Gaussian::pi_tau_combined", |bencher| {
        bencher.iter(|| {
            let pi = g1.pi();
            let tau = g1.tau();
            (pi, tau)
        });
    });
}

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