///|
/// 02-calibration-chamfer-block
///
/// A working example that generates a STEP model for a print-tuning block that
/// sweeps chamfers/fillets around the top edge.
///
/// Usage (stdout):
///   moon run --target native examples/02-calibration-chamfer-block -- > block.step
///
/// Usage (write file):
///   moon run --target native examples/02-calibration-chamfer-block -- -o block.step
///
/// Chamfer vs fillet:
/// - If --filletRadius > 0, it takes precedence and we generate a stepped (faceted)
///   fillet-like top profile.
/// - Otherwise, we generate a simple chamfer using --chamferSize.
///
/// Try:
///   moon run --target native examples/02-calibration-chamfer-block -- -o block.step --chamferSize 0.8
///   moon run --target native examples/02-calibration-chamfer-block -- -o block.step --filletRadius 1.2
///   moon run --target native examples/02-calibration-chamfer-block -- -o block.step --length 40 --width 20 --height 10
///
/// Translate examples:
///   moon run --target native examples/02-calibration-chamfer-block -- -t 10,0,0 -o block.step
async fn validate_dims(
  length_mm : Double,
  width_mm : Double,
  height_mm : Double,
  chamfer_size_mm : Double,
  fillet_radius_mm : Double,
) -> Bool {
  let min_xy = if length_mm < width_mm { length_mm } else { width_mm }
  let min_xy_half = min_xy / 2.0
  if chamfer_size_mm < 0.0 {
    @cli.eprintln("error: --chamferSize must be >= 0")
    return false
  }
  if fillet_radius_mm < 0.0 {
    @cli.eprintln("error: --filletRadius must be >= 0")
    return false
  }
  if chamfer_size_mm > min_xy_half {
    @cli.eprintln("error: --chamferSize is too large for the block footprint")
    return false
  }
  if fillet_radius_mm > min_xy_half {
    @cli.eprintln("error: --filletRadius is too large for the block footprint")
    return false
  }
  if fillet_radius_mm > 0.0 && fillet_radius_mm > height_mm {
    @cli.eprintln("error: --filletRadius must be <= --height")
    return false
  }
  true
}

///|
async fn main {
  let base_args_spec = {
    "length": @cli.opt_double(
      50.0,
      help="Block length (mm)",
      min=0.0,
      min_exclusive=true,
    ),
    "width": @cli.opt_double(
      20.0,
      help="Block width (mm)",
      min=0.0,
      min_exclusive=true,
    ),
    "height": @cli.opt_double(
      12.0,
      help="Block height (mm)",
      min=0.0,
      min_exclusive=true,
    ),
    "chamferSize": @cli.opt_double(
      1.0,
      help="Top-edge chamfer size (mm). Ignored when --filletRadius > 0.",
      min=0.0,
    ),
    "filletRadius": @cli.opt_double(
      0.0,
      help="Top-edge fillet radius (mm). When > 0, takes precedence over chamfer.",
      min=0.0,
    ),
  }
  let args_spec = @cli.with_translate(@common.with_output_args(base_args_spec))
  guard @cli.parse(
      args_spec,
      prog="02-calibration-chamfer-block",
      description="Generate a chamfer/fillet calibration block STEP model.",
    )
    is Some(args) else {
    return
  }
  let length_mm = args.double("length")
  let width_mm = args.double("width")
  let height_mm = args.double("height")
  let chamfer_size_mm = args.double("chamferSize")
  let fillet_radius_mm = args.double("filletRadius")
  let output = @common.output_paths(args)
  let (tx, ty, tz) = match args.translate_xyz() {
    Some(v) => v
    None => {
      @cli.eprintln("error: invalid translation")
      abort("")
    }
  }
  if !validate_dims(
      length_mm, width_mm, height_mm, chamfer_size_mm, fillet_radius_mm,
    ) {
    @cli.eprintln("error: invalid dimensions")
    abort("")
  }
  let block = @cad.CalibrationChamferBlock::new(
      length_mm,
      width_mm,
      height_mm,
      chamfer_size_mm~,
      fillet_radius_mm~,
      // This is an internal quality knob; keep the CLI simple.
      fillet_segments=10,
    )
    .with_name("calibration-block")
    .translate(x=tx, y=ty, z=tz)
  let design = @cad.Design::new(
    name="calibration-chamfer-block",
    documentation=args.documentation(),
  ).add(block)
  @common.write_output(design, output)
}