///|
/// 40-face-query-hole
///
/// MakerCad-style relative modeling: compile a block, query its planar faces,
/// pick the upward-facing one, and cut a hole centered on it. The query and
/// placement are deterministic; use `--eval` to have OCCT evaluate the cut
/// into a real, trimmed B-Rep.
///
/// Usage:
///   ./examples/run-example.sh 40 --eval=hole.step --png=hole.png
///   ./examples/run-example.sh 40 -o block.step        # nominal STEP
///
/// Options:
///   --length/-l  Block length in mm (default 40)
///   --width/-w   Block width in mm (default 30)
///   --height     Block height in mm (default 10)
///   --hole/-d    Hole diameter in mm (default 8)
async fn main {
  let base_args_spec = {
    "length": @cli.opt_double(
      40.0,
      short='l',
      help="Block length in millimeters",
      min=0.0,
      min_exclusive=true,
    ),
    "width": @cli.opt_double(
      30.0,
      short='w',
      help="Block width in millimeters",
      min=0.0,
      min_exclusive=true,
    ),
    "height": @cli.opt_double(
      10.0,
      help="Block height in millimeters",
      min=0.0,
      min_exclusive=true,
    ),
    "hole": @cli.opt_double(
      8.0,
      short='d',
      help="Hole diameter in millimeters",
      min=0.0,
      min_exclusive=true,
    ),
  }
  let args_spec = @common.with_output_args(
    base_args_spec,
    out_help="Write STEP output to a file (default: stdout)",
    eval_help="Evaluate the cut with OCCT and write a real trimmed STEP file",
  )
  guard @cli.parse(
      args_spec,
      prog="40-face-query-hole",
      description="Cut a hole into a block's top face discovered by face query.",
    )
    is Some(args) else {
    return
  }
  let length = args.double("length")
  let width = args.double("width")
  let height = args.double("height")
  let hole_diameter = args.double("hole")
  let output = @common.output_paths(args)
  let block = @cad.Cuboid::new(length, width, height)
    .with_name("block")
    .with_color(@cad.Rgb::blue())
  // Query the compiled block's planar faces, keeping the one facing +Z.
  let top = match
    @cad.Design::new(name="probe")
    .add(block)
    .planar_faces()
    .aligned_with((0.0, 0.0, 1.0))
    .sort_by_z(ascending=false)
    .first_matching(fn(_f) { true }) {
    Some(face) => face
    None => {
      @cli.eprintln("error: no upward-facing planar face found")
      abort("")
    }
  }
  // The face frame is the sketch plane: center the hole on the face.
  let center = top.local_xy(top.center())
  let profile = @cad.Profile2D::new(
    @cad.Profile2D::circle(hole_diameter, segments=48),
  )
  let design = @cad.Design::new(
    name="face-query-hole",
    documentation=args.documentation(),
  ).add(
    @cad.cut_on_face(
      block,
      profile,
      top,
      height,
      name="block-with-hole",
      center~,
    ),
  )
  @common.write_output(design, output)
}