//! Benchmark for transform composition.
//!
//! Stage 1 test criterion: 1M transform multiplications must complete under
//! 10ms. The `compose_1m` benchmark below measures exactly that workload; check
//! its reported time against the 10ms budget.

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use oxide_engine::math::{Quat, Transform, Vec3};

fn compose_1m(c: &mut Criterion) {
    // A representative non-trivial transform (uniform scale → exact fast path).
    let a = Transform::from_trs(
        Vec3::new(1.0, 2.0, 3.0),
        Quat::from_euler(glam::EulerRot::XYZ, 0.3, 0.5, 0.7),
        Vec3::splat(1.5),
    );
    let b = Transform::from_trs(
        Vec3::new(-2.0, 0.5, 4.0),
        Quat::from_rotation_y(0.9),
        Vec3::splat(0.8),
    );

    c.bench_function("compose_1m", |bencher| {
        bencher.iter(|| {
            // Compose 1M times. Inputs are re-fetched through `black_box` each
            // iteration so the optimizer can neither hoist the call nor let the
            // accumulated values blow up to infinity; the product is consumed.
            let mut acc = Vec3::ZERO;
            for _ in 0..1_000_000 {
                let product = black_box(a).mul_transform(&black_box(b));
                acc += product.translation;
            }
            black_box(acc)
        });
    });
}

fn point_transform_1m(c: &mut Criterion) {
    let t = Transform::from_trs(
        Vec3::new(1.0, 2.0, 3.0),
        Quat::from_rotation_z(0.6),
        Vec3::splat(2.0),
    );
    c.bench_function("transform_point_1m", |bencher| {
        bencher.iter(|| {
            let mut acc = Vec3::ZERO;
            for i in 0..1_000_000u32 {
                let p = Vec3::splat(i as f32 * 1e-6);
                acc += t.transform_point(black_box(p));
            }
            black_box(acc)
        });
    });
}

criterion_group!(benches, compose_1m, point_transform_1m);
criterion_main!(benches);
