///|
pub fn execute_cli(args : Array[String]) -> String {
  let catalog = bundled_catalog()
  if args.length() == 0 || args[0] == "--help" || args[0] == "help" {
    return cli_usage()
  }
  match args[0] {
    "check" if args.length() >= 2 =>
      format_report(validate_against(catalog, args[1]))
    "chapter" if args.length() >= 2 => cli_chapter(catalog, args[1])
    "prefix" if args.length() >= 2 => cli_entries(catalog.prefix(args[1]))
    "search" if args.length() >= 2 => cli_entries(catalog.search_title(args[1]))
    "batch" if args.length() >= 2 =>
      render_batch_text(validate_batch(catalog, split_cli_values(args[1])))
    "stats" => cli_stats(catalog)
    _ => cli_usage()
  }
}

///|
fn cli_usage() -> String {
  (
    #|icd-check - MoonBit ICD coding toolkit
    #|
    #|Usage:
    #|  moon run cmd/main -- check I10
    #|  moon run cmd/main -- chapter J45
    #|  moon run cmd/main -- prefix A00
    #|  moon run cmd/main -- search diabetes
    #|  moon run cmd/main -- batch I10,B20,bad
    #|  moon run cmd/main -- stats
  )
}

///|
fn cli_chapter(catalog : Catalog, input : String) -> String {
  match catalog.lookup(input) {
    Some(entry) => {
      let chapter = icd10_chapters()
        .search_by(fn(item) { item.id == entry.chapter_id })
        .map(fn(i) { icd10_chapters()[i] })
      match chapter {
        Some(value) =>
          value.id + " " + value.start + "-" + value.end + ": " + value.title
        None => "No chapter resolved for " + input
      }
    }
    None => {
      let report = validate_against(catalog, input)
      match report.chapter {
        Some(value) =>
          value.id + " " + value.start + "-" + value.end + ": " + value.title
        None => "No chapter resolved for " + input
      }
    }
  }
}

///|
fn cli_entries(entries : Array[IcdEntry]) -> String {
  if entries.is_empty() {
    "No matching entries"
  } else {
    entries.map(fn(entry) { entry.code + "\t" + entry.title }).join("\n")
  }
}

///|
fn cli_stats(catalog : Catalog) -> String {
  let counts = icd10_chapters()
    .map(fn(chapter) {
      chapter.id + "=" + catalog.in_chapter(chapter.id).length().to_string()
    })
    .join(", ")
  "catalog entries: " + catalog.len().to_string() + "\n" + counts
}

///|
fn split_cli_values(value : String) -> Array[String] {
  let values = []
  let mut current = ""
  for c in value {
    if c == ',' {
      values.push(current.trim().to_owned())
      current = ""
    } else {
      current = current + c.to_string()
    }
  }
  if !current.trim().is_empty() {
    values.push(current.trim().to_owned())
  }
  values
}