/// MoonProbe - cli
///
/// The command-line entry point: locate the suite, read it, parse it, execute
/// every case through the runner and hand the results to the reporter. When
/// `--junit ` is given, the run is also written out as JUnit XML.

///|
/// Print the usage message.
fn print_usage() -> Unit {
  println("MoonProbe - a declarative API test runner")
  println("")
  println(
    "Usage: moonprobe  [--junit ]",
  )
  println("")
  println("Example:")
  println("  moon run cli --target js -- examples/httpbin.probe")
  println(
    "  moon run cli --target js -- examples/httpbin.probe --junit junit.xml",
  )
}

///|
/// Pick the `.probe` path out of the command line.
///
/// The leading arguments differ per backend — on the `js` target the Node.js
/// executable and the generated script come first — so the suite is selected by
/// file extension instead of by position. The last match wins, which keeps
/// `--examples/demo.probe`-style overrides working.
fn suite_path(args : Array[String]) -> String? {
  let mut i = args.length()
  while i > 0 {
    i = i - 1
    if args[i].has_suffix(".probe") {
      return Some(args[i])
    }
  }
  return None
}

///|
/// The path given after `--junit`, if any.
fn junit_path(args : Array[String]) -> String? {
  let mut i = 0
  while i + 1 < args.length() {
    if args[i] == "--junit" {
      return Some(args[i + 1])
    }
    i = i + 1
  }
  return None
}

///|
fn main {
  let args = @env.args()
  let path = match suite_path(args) {
    Some(path) => path
    None => {
      print_usage()
      return
    }
  }
  let source = match read_source(path) {
    Ok(source) => source
    Err(msg) => {
      println("error: \{msg}")
      return
    }
  }
  let suite = match @parser.parse(source) {
    Ok(suite) => suite
    Err(msg) => {
      println("error: \{path}: \{msg}")
      return
    }
  }
  let started = @env.now()
  let results = match @runner.run_suite(suite) {
    Ok(results) => results
    Err(msg) => {
      println("error: \{msg}")
      return
    }
  }
  let elapsed = @env.now() - started
  @reporter.print_report(results, elapsed)
  match junit_path(args) {
    Some(out) =>
      match write_report(out, @reporter.to_junit_xml(results, elapsed)) {
        Ok(_) => println("JUnit XML written to \{out}")
        Err(msg) => println("error: \{msg}")
      }
    None => ()
  }
}