///|
/// 12-tube-cap-assortment
///
/// A parametric tube cap generator. Can create either "caps" (fitting over
/// the outside of a tube) or "plugs" (fitting inside a tube).
///
/// Usage (stdout):
///   moon run --target native examples/12-tube-cap-assortment -- --diameter 20 --wall 1.5 > cap.step
///
/// Usage (write file):
///   moon run --target native examples/12-tube-cap-assortment -- -o cap.step
async fn main {
  let base_args_spec = {
    "diameter": @cli.opt_double(
      25.4,
      help="Target tube diameter (mm)",
      min=0.0,
      min_exclusive=true,
    ),
    "wall": @cli.opt_double(
      2.0,
      help="Wall thickness of the cap/plug (mm)",
      min=0.0,
      min_exclusive=true,
    ),
    "height": @cli.opt_double(
      15.0,
      help="Height of the fitting part (mm)",
      min=0.0,
      min_exclusive=true,
    ),
    "topThickness": @cli.opt_double(
      3.0,
      help="Thickness of the cap top (mm)",
      min=0.0,
      min_exclusive=true,
    ),
    "clearance": @cli.opt_double(
      0.2,
      help="Radial clearance for the fit (mm)",
      min=0.0,
    ),
    "type": @cli.opt_string(
      help="Type of fitting: 'cap' (over tube) or 'plug' (inside tube)",
    ),
  }
  let args_spec = @cli.with_translate(@common.with_output_args(base_args_spec))
  guard @cli.parse(
      args_spec,
      prog="37-tube-cap-assortment",
      description="Generate a parametric tube cap or plug.",
    )
    is Some(args) else {
    return
  }
  let target_dia = args.double("diameter")
  let wall = args.double("wall")
  let fitting_height = args.double("height")
  let top_thickness = args.double("topThickness")
  let clearance = args.double("clearance")
  let is_plug = args.string_opt("type").unwrap_or("cap") == "plug"
  let output = @common.output_paths(args)
  let (tx, ty, tz) = match args.translate_xyz() {
    Some(v) => v
    None => {
      @cli.eprintln("error: invalid translation")
      abort("")
    }
  }

  // Calculate dimensions based on type
  let (fitting_od, fitting_id, top_dia) = if is_plug {
    // Plug: fits INSIDE tube
    // Fitting OD = Tube ID - clearance
    // Top OD = Tube OD (approx)
    let f_od = target_dia - 2.0 * clearance
    let f_id = f_od - 2.0 * wall
    (f_od, f_id, target_dia + 2.0 * wall)
  } else {
    // Cap: fits OVER tube
    // Fitting ID = Tube OD + clearance
    // Fitting OD = Fitting ID + 2*wall
    let f_id = target_dia + 2.0 * clearance
    let f_od = f_id + 2.0 * wall
    (f_od, f_id, f_od)
  }

  // 1. The Top Plate (solid disk)
  let top = @cad.Cylinder::new(top_dia, top_thickness)
    .with_name("cap-top")
    .with_color(@cad.Rgb::orange())
    .translate(x=tx, y=ty, z=tz + fitting_height)

  // 2. The Fitting Wall (hollow cylinder)
  let wall_part = @cad.tube(fitting_od, fitting_id, fitting_height)
    .with_name("cap-wall")
    .with_color(@cad.Rgb::blue())
    .translate(x=tx, y=ty, z=tz)

  //
  let design = @cad.Design::new(
      name="tube-cap",
      documentation=args.documentation(),
    )
    .add(top)
    .add(wall_part)
  @common.write_output(design, output)
}