///|
pub fn command_help() -> String {
  "QuireLoom --job  [--format manifest|csv|normalize|proof|atlas]\nproof: --sheet <1-based> [--back]\natlas: --first <1-based> --count <1..64>\nInput is inline JSON; use shell file reading to pass a saved job. Output is stdout.\n"
}

///|
fn command_number(
  value : String,
  field : String,
) -> Result[Int32, WorkflowError] {
  match selection_number(value, 0) {
    Ok((number, end)) if end == value.length() => Ok(number)
    _ => Err(workflow_error(field, "expected a decimal integer in 1..100000"))
  }
}

///|
/// Pure command adapter: argv excludes the runtime/program names.
pub fn run_command(args : Array[String]) -> Result[String, WorkflowError] {
  if args.is_empty() || (args.length() == 1 && args[0] == "--help") {
    return Ok(command_help())
  }
  let options : Map[String, String] = Map([])
  let mut index = 0
  while index < args.length() {
    let key = args[index]
    if !["--job", "--format", "--sheet", "--back", "--first", "--count"].contains(
        key,
      ) {
      return Err(workflow_error("argv[\{index}]", "unknown option: " + key))
    }
    if options.contains(key) {
      return Err(workflow_error(key, "duplicate option"))
    }
    if key == "--back" {
      options.set(key, "true")
      index += 1
    } else {
      if index + 1 >= args.length() {
        return Err(workflow_error(key, "missing option value"))
      }
      options.set(key, args[index + 1])
      index += 2
    }
  }
  let text = match options.get("--job") {
    Some(text) => text
    None => return Err(workflow_error("--job", "a JSON job is required"))
  }
  let format = options.get("--format").unwrap_or("manifest")
  if !["manifest", "csv", "normalize", "proof", "atlas"].contains(format) {
    return Err(workflow_error("--format", "unknown output format"))
  }
  for key in ["--sheet", "--back", "--first", "--count"] {
    if options.contains(key) {
      let allowed = if format == "proof" {
        key == "--sheet" || key == "--back"
      } else if format == "atlas" {
        key == "--first" || key == "--count"
      } else {
        false
      }
      if !allowed {
        return Err(
          workflow_error(key, "option does not apply to this output format"),
        )
      }
    }
  }
  let spec = match parse_job(text) {
    Ok(spec) => spec
    Err(e) => return Err(e)
  }
  if format == "normalize" {
    return job_spec_json(spec)
  }
  let job = match build_job(spec) {
    Ok(job) => job
    Err(e) => return Err(e)
  }
  match format {
    "csv" => job_csv(job)
    "proof" => {
      let sheet = match
        command_number(options.get("--sheet").unwrap_or("1"), "--sheet") {
        Ok(n) => n
        Err(e) => return Err(e)
      }
      job_proof(job, sheet - 1, options.contains("--back"))
    }
    "atlas" => {
      let first = match
        command_number(options.get("--first").unwrap_or("1"), "--first") {
        Ok(n) => n
        Err(e) => return Err(e)
      }
      let count = match
        command_number(options.get("--count").unwrap_or("1"), "--count") {
        Ok(n) => n
        Err(e) => return Err(e)
      }
      proof_atlas(job, first - 1, count)
    }
    _ => job_manifest(job)
  }
}