// Performance benchmark suite for FFT algorithms and GNLSE solvers.

///|
/// Run FFT performance benchmark over 100 iterations
pub fn benchmark_fft_performance(n_points : Int) -> Double {
  let data = Array::make(n_points, @types.Complex::zero())
  for i = 0; i < n_points; i = i + 1 {
    data[i] = @types.Complex::new(i.to_double(), -0.5 * i.to_double())
  }

  // Execute 100 transforms
  for _iter = 0; _iter < 100; _iter = _iter + 1 {
    let _spec = @fft.fft(data)
  }

  n_points.to_double() * 100.0
}

///|
/// Run SSFM solver benchmark over 100 propagation steps
pub fn benchmark_ssfm_solver(solver : @types.SolverMethod) -> Int {
  let p_cfg = @types.PulseConfig::default()
  let pulse = @pulse.generate_pulse(p_cfg)
  let fiber = @fiber.smf28_fiber(10.0)
  let sim_cfg = @types.SimulationConfig::new(
    solver_method=solver,
    num_steps=100,
  )

  let res = @ssfm.run_simulation(pulse, fiber, sim_cfg)
  res.total_steps
}

///|
/// Measure 100 fixed-size FFT transforms using the monotonic core benchmark clock.
fn benchmark_fft_elapsed_microseconds(n_points : Int) -> Double {
  let data = Array::make(n_points, @types.Complex::zero())
  for i = 0; i < n_points; i = i + 1 {
    data[i] = @types.Complex::new(i.to_double(), -0.5 * i.to_double())
  }
  let start = @bench.monotonic_clock_start()
  for _iter = 0; _iter < 100; _iter = _iter + 1 {
    ignore(@fft.fft(data))
  }
  @bench.monotonic_clock_end(start)
}

///|
/// Measure one fixed 100-step SSFM propagation using the monotonic benchmark clock.
fn benchmark_ssfm_elapsed_microseconds(solver : @types.SolverMethod) -> Double {
  let p_cfg = @types.PulseConfig::default()
  let pulse = @pulse.generate_pulse(p_cfg)
  let fiber = @fiber.smf28_fiber(10.0)
  let sim_cfg = @types.SimulationConfig::new(
    solver_method=solver,
    num_steps=100,
  )
  let start = @bench.monotonic_clock_start()
  ignore(@ssfm.run_simulation(pulse, fiber, sim_cfg))
  @bench.monotonic_clock_end(start)
}