use audio_samples::operations::types::StereoConversionMethod;
use audio_samples::{AudioChannelOps, AudioProcessing, sine_wave};
use criterion::{Criterion, black_box, criterion_group, criterion_main};
use std::time::Duration;

fn bench_channels_to_mono(c: &mut Criterion) {
    let audio = sine_wave::<f32, f32>(440.0, Duration::from_secs_f32(0.5), 44100, 0.5)
        .duplicate_to_channels(2)
        .unwrap();
    c.bench_function("channels::to_mono_average", |b| {
        b.iter(|| {
            black_box(
                audio
                    .to_mono::<f32>(audio_samples::operations::types::MonoConversionMethod::Average)
                    .unwrap(),
            )
        })
    });
}

fn bench_channels_duplicate_scale(c: &mut Criterion) {
    let audio = sine_wave::<f32, f32>(440.0, Duration::from_secs_f32(0.5), 44100, 0.5);
    c.bench_function("channels::duplicate_and_scale", |b| {
        b.iter(|| {
            let mut a = audio.clone();
            let _ = a.duplicate_to_channels(4).unwrap();
            a.scale(0.5f32);
            black_box(&a);
        })
    });
}

fn bench_channels_to_stereo_and_pan(c: &mut Criterion) {
    let mono = sine_wave::<f32, f32>(440.0, Duration::from_secs_f32(0.4), 44100, 0.6);
    c.bench_function("channels::to_stereo_duplicate", |b| {
        b.iter(|| {
            let _ = mono
                .to_stereo::<f32>(StereoConversionMethod::Duplicate)
                .unwrap();
        })
    });

    c.bench_function("channels::to_stereo_pan", |b| {
        b.iter(|| {
            let _ = mono
                .to_stereo::<f32>(StereoConversionMethod::Pan(0.25f32))
                .unwrap();
        })
    });
}

fn bench_channels_extract_swap_pan_duplicate_to_n(c: &mut Criterion) {
    let mono = sine_wave::<f32, f32>(330.0, Duration::from_secs_f32(0.4), 44100, 0.7);
    let stereo = mono.duplicate_to_channels(2).unwrap();

    c.bench_function("channels::extract_channel", |b| {
        b.iter(|| {
            let _ = stereo.extract_channel(0).unwrap();
        })
    });

    c.bench_function("channels::swap_channels", |b| {
        b.iter(|| {
            let mut s = stereo.clone();
            let _ = s.swap_channels(0, 1).unwrap();
            black_box(&s);
        })
    });

    c.bench_function("channels::pan", |b| {
        b.iter(|| {
            let mut s = stereo.clone();
            let _ = s.pan(0.5f32).unwrap();
            black_box(&s);
        })
    });

    c.bench_function("channels::duplicate_to_6", |b| {
        b.iter(|| {
            let _ = mono.duplicate_to_channels(6).unwrap();
        })
    });
}

criterion_group!(
    benches,
    bench_channels_to_mono,
    bench_channels_duplicate_scale,
    bench_channels_to_stereo_and_pan,
    bench_channels_extract_swap_pan_duplicate_to_n
);
criterion_main!(benches);
