// Main CLI entrance and simulation demonstration runner.

///|
/// Print ASCII Banner
pub fn print_banner() -> Unit {
  println(
    "==========================================================================",
  )
  println(
    "  MoonBit Nonlinear Fiber Optics & SSFM Simulator (moonbit-nlse-ssfm)     ",
  )
  println(
    "  Solve GNLSE: Split-Step Fourier Method / RK4IP / Raman / Self-Steepening ",
  )
  println(
    "==========================================================================",
  )
}

///|
/// Main entry execution
fn main {
  print_banner()

  println(
    "\n--- Demo 1: Fundamental Soliton (N=1) Invariance Baseline Check ---",
  )
  let p_cfg = @types.PulseConfig::new(
    shape=@types.PulseShape::sech(),
    peak_power=100.0,
    fwhm_duration=1.0e-12,
    central_wavelength=@types.WAVELENGTH_1550NM,
    time_window=50.0e-12,
    num_points=1024,
  )
  let initial_pulse = @pulse.generate_pulse(p_cfg)

  let t0 = 1.0e-12 / (2.0 * @math.ln(1.0 + @math.pow(2.0, 0.5)))
  let beta2 = -2.0e-26
  let gamma_soliton = -beta2 / (100.0 * t0 * t0)

  let disp = @types.DispersionProfile::new(beta2~, beta3=0.0)
  let nonlin = @types.NonlinearProfile::new(
    gamma=gamma_soliton,
    enable_raman=false,
    self_steepening=false,
  )
  let fiber = @types.FiberSegment::new("Soliton-SMF", 20.0, disp, nonlin)

  let sim_cfg = @types.SimulationConfig::new(
    solver_method=@types.SolverMethod::rk4ip(),
    num_steps=200,
  )

  let res = @ssfm.run_simulation(initial_pulse, fiber, sim_cfg)
  let fwhm_in = @analyzer.calculate_fwhm_duration(initial_pulse)
  let fwhm_out = @analyzer.calculate_fwhm_duration(res.final_pulse)
  let p_in = @pulse.pulse_peak_power(initial_pulse)
  let p_out = @pulse.pulse_peak_power(res.final_pulse)

  println(
    "  Initial Pulse FWHM : " +
    (fwhm_in * 1.0e12).to_string() +
    " ps, Peak Power: " +
    p_in.to_string() +
    " W",
  )
  println(
    "  Final Pulse FWHM   : " +
    (fwhm_out * 1.0e12).to_string() +
    " ps, Peak Power: " +
    p_out.to_string() +
    " W",
  )
  println(
    "  Peak Power Stability Error: " +
    ((p_out - p_in) / p_in * 100.0).to_string() +
    "%",
  )

  println("\n--- Demo 2: Fiber Amplifier Optical Similariton Generation ---")
  let edf = @fiber.edf_gain_fiber(3.0, 12.0)
  let amp_res = @amplifier.run_amplifier_simulation(
    initial_pulse, edf, 50.0e12, 100,
  )
  let e_in = @pulse.pulse_energy(initial_pulse)
  let e_out = @pulse.pulse_energy(amp_res.final_pulse)
  println("  Amplifier Input Energy : " + (e_in * 1.0e9).to_string() + " nJ")
  println("  Amplifier Output Energy: " + (e_out * 1.0e9).to_string() + " nJ")

  println("\n--- Demo 3: Femtosecond Supercontinuum Generation in PCF ---")
  let sc_cfg = @types.PulseConfig::new(
    shape=@types.PulseShape::sech(),
    peak_power=500.0,
    fwhm_duration=50.0e-15,
    central_wavelength=@types.WAVELENGTH_800NM,
    time_window=10.0e-12,
    num_points=1024,
  )
  let pump = @pulse.generate_pulse(sc_cfg)
  let sc_res = @supercontinuum.run_supercontinuum_simulation(pump, 0.05, 50)
  println("  Supercontinuum steps executed: " + sc_res.total_steps.to_string())

  println("\n--- Demo 4: Manakov Vector NLSE Birefringent Propagation ---")
  let py = @pulse.generate_pulse(p_cfg)
  let vpulse = @vector_nlse.VectorPulse::new(initial_pulse, py)
  let omega = @fft.angular_frequency_grid(
    initial_pulse.field.length(),
    initial_pulse.dt,
  )
  let d_hat = @fiber.compute_dispersion_operator(fiber.dispersion, omega)
  let d_half = @fiber.compute_dispersion_step_half(d_hat, 0.1)
  let (fx_n, fy_n) = @vector_nlse.step_manakov_vector(
    vpulse.pulse_x.field,
    vpulse.pulse_y.field,
    d_half,
    d_half,
    fiber.nonlinearity.gamma,
    2.0 / 3.0,
    0.1,
  )
  println(
    "  Vector NLSE step completed, X/Y array length: " +
    fx_n.length().to_string() +
    "/" +
    fy_n.length().to_string(),
  )

  println("\n--- Demo 5: Pure MoonBit SVG Plot Generation ---")
  let svg = @viz.render_pulse_svg(
    res.final_pulse,
    800,
    400,
    "Fundamental Soliton Invariance Baseline",
  )
  println("  Generated SVG character count: " + svg.length().to_string())

  println("\n--- Benchmarks ---")
  let bench_ops = benchmark_fft_performance(2048)
  println("  FFT Benchmark points processed: " + bench_ops.to_string())
  let fft_elapsed_us = benchmark_fft_elapsed_microseconds(2048)
  println("  FFT elapsed (100 x 2048): " + fft_elapsed_us.to_string() + " us")
  let rk4ip_steps = benchmark_ssfm_solver(@types.SolverMethod::rk4ip())
  println("  RK4IP Solver steps requested: 100")
  println("  RK4IP Solver steps executed: " + rk4ip_steps.to_string())
  let rk4ip_elapsed_us = benchmark_ssfm_elapsed_microseconds(
    @types.SolverMethod::rk4ip(),
  )
  println(
    "  RK4IP elapsed (requested 100 steps): " +
    rk4ip_elapsed_us.to_string() +
    " us",
  )

  println(
    "\n==========================================================================",
  )
  println("  Simulation Completed Successfully!")
  println(
    "==========================================================================",
  )
}