///|
/// Reusable scenario presets for examples and parameter sweeps.
pub(all) enum Preset {
  Poiseuille
  LidDrivenCavity
  CylinderWake
  ScalarDiffusion
} derive(Debug, Eq)

///|
/// Return a stable human-readable preset name.
pub fn preset_name(preset : Preset) -> String {
  match preset {
    Poiseuille => "poiseuille"
    LidDrivenCavity => "lid-driven-cavity"
    CylinderWake => "cylinder-wake"
    ScalarDiffusion => "scalar-diffusion"
  }
}

///|
/// Return default lattice dimensions for a preset.
pub fn preset_size(preset : Preset) -> Size {
  match preset {
    Poiseuille => Size::new(width=64, height=24)
    LidDrivenCavity => Size::new(width=40, height=40)
    CylinderWake => Size::new(width=96, height=36)
    ScalarDiffusion => Size::new(width=64, height=32)
  }
}

///|
/// Return conservative collision settings for a preset.
pub fn preset_options(preset : Preset) -> SimulationOptions {
  match preset {
    Poiseuille =>
      SimulationOptions::new(
        model=CollisionModel::mrt(omega=1.0),
        force_x=0.00001,
      )
    LidDrivenCavity =>
      SimulationOptions::new(model=CollisionModel::regularized(omega=1.0))
    CylinderWake =>
      SimulationOptions::new(
        model=CollisionModel::mrt(omega=1.0),
        force_x=0.00001,
      )
    ScalarDiffusion =>
      SimulationOptions::new(
        model=CollisionModel::bgk(omega=1.0),
        boundary=Periodic,
      )
  }
}

///|
/// Return a demonstration step count.
pub fn recommended_steps(preset : Preset) -> Int {
  match preset {
    Poiseuille => 500
    LidDrivenCavity => 800
    CylinderWake => 600
    ScalarDiffusion => 200
  }
}

///|
/// Return the expected output family for a preset.
pub fn preset_output_kind(preset : Preset) -> String {
  match preset {
    Poiseuille => "profile,csv,png"
    LidDrivenCavity => "vorticity,csv,png"
    CylinderWake => "wake,force,csv,png"
    ScalarDiffusion => "scalar,ppm,vtk"
  }
}

///|
/// Build the matching high-level legacy scenario.
pub fn legacy_preset(preset : Preset) -> Lattice? {
  match preset {
    Poiseuille => Some(poiseuille(width=64, height=24))
    LidDrivenCavity => Some(lid_driven_cavity(size=40))
    CylinderWake => Some(cylinder_wake(width=96, height=36))
    ScalarDiffusion => None
  }
}

///|
/// Return the estimated characteristic velocity of a preset.
pub fn preset_velocity(preset : Preset) -> Double {
  match preset {
    Poiseuille => 0.0002
    LidDrivenCavity => 0.08
    CylinderWake => 0.04
    ScalarDiffusion => 0.0
  }
}

///|
/// Return a compact preset description.
pub fn preset_description(preset : Preset) -> String {
  "\{preset_name(preset)}: \{preset_size(preset).width}x\{preset_size(preset).height}, steps=\{recommended_steps(preset)}, output=\{preset_output_kind(preset)}"
}