// Argument parsing for the portable robots-tool CLI.

///|
struct CliOptions {
  mut text : String
  mut text_set : Bool
  mut agent : String
  mut path : String
  mut limits : String
  mut help : Bool
  positionals : Array[String]
  mut unknown : String
}

///|
fn empty_options() -> CliOptions {
  {
    text: "",
    text_set: false,
    agent: "",
    path: "",
    limits: "default",
    help: false,
    positionals: Array::new(),
    unknown: "",
  }
}

///|
fn known_command(cmd : String) -> Bool {
  cmd == "parse" ||
  cmd == "validate" ||
  cmd == "check" ||
  cmd == "format" ||
  cmd == "audit" ||
  cmd == "stats" ||
  cmd == "help" ||
  cmd == "version" ||
  cmd == "--help" ||
  cmd == "--version"
}

///|
fn split_command(args : Array[String]) -> (String, Array[String]) {
  if args.is_empty() {
    return ("help", Array::new())
  }
  let mut start = 0
  if !known_command(args[0]) {
    start = 1
  }
  if start >= args.length() {
    return ("help", Array::new())
  }
  let cmd = if args[start] == "--help" {
    "help"
  } else if args[start] == "--version" {
    "version"
  } else {
    args[start]
  }
  let rest = Array::new()
  for i = start + 1; i < args.length(); i = i + 1 {
    rest.push(args[i])
  }
  (cmd, rest)
}

///|
fn parse_options(args : Array[String]) -> CliOptions {
  let o = empty_options()
  let mut i = 0
  while i < args.length() {
    let a = args[i]
    if a == "--text" || a == "--agent" || a == "--path" || a == "--limits" {
      let value = if i + 1 < args.length() { args[i + 1] } else { "" }
      if a == "--text" {
        o.text = value
        o.text_set = true
      } else if a == "--agent" {
        o.agent = value
      } else if a == "--path" {
        o.path = value
      } else if a == "--limits" {
        o.limits = value
      }
      i = i + 2
    } else if a == "--help" || a == "-h" {
      o.help = true
      i = i + 1
    } else if a.has_prefix("-") {
      o.unknown = a
      i = i + 1
    } else {
      o.positionals.push(a)
      i = i + 1
    }
  }
  o
}

///|
fn resolve_limits(name : String) -> @robots.Limits {
  if name == "strict" {
    @robots.Limits::strict()
  } else if name == "permissive" {
    @robots.Limits::permissive()
  } else {
    @robots.Limits::default()
  }
}

///|
fn input_text(o : CliOptions) -> String {
  if o.text_set {
    o.text
  } else if o.positionals.length() > 0 {
    o.positionals[0]
  } else {
    ""
  }
}