///|
fn main {
  let cmd = build_command()
  try {
    let matches = cmd.parse()
    let out = @fakefetch.render(matches.to_options()).trim_end(chars="\n")
    @miniio.stdout.write_text(out)
    @miniio.stdout.write_text("\n")
  } catch {
    err => @miniio.stdout.write_text(err.to_string()) catch { _ => () }
  }
}

///|
/// Value provided by the user on the command line, if any. Distinct from the
/// argparse default_values, which are only set for the color option.
fn @clap.Matches::first_value(self : @clap.Matches, name : String) -> String? {
  self.values.get(name).bind(arr => arr.get(0))
}

///|
fn @clap.Matches::to_options(matches : @clap.Matches) -> @fakefetch.Options {
  {
    model: matches.first_value("model"),
    user: matches.first_value("user"),
    host: matches.first_value("host"),
    os: matches.first_value("os"),
    device: matches.first_value("device"),
    kernel: matches.first_value("kernel"),
    uptime: matches.first_value("uptime"),
    shell: matches.first_value("shell"),
    resolution: matches.first_value("resolution"),
    de: matches.first_value("de"),
    wm: matches.first_value("wm"),
    wm_theme: matches.first_value("wm-theme"),
    terminal: matches.first_value("terminal"),
    term_font: matches.first_value("term-font"),
    cpu: matches.first_value("cpu"),
    gpu: matches.first_value("gpu"),
    memory: matches.first_value("memory"),
    logo: matches.first_value("logo"),
    color: matches.first_value("color"),
    no_logo: matches.flags.get("no-logo").unwrap_or(false),
  }
}

///|
fn build_command() -> @clap.Command {
  @clap.Command(
    "ffetch",
    about="Print system information that looks like fastfetch output",
    flags=[@clap.FlagArg("no-logo", about="Do not print a logo")],
    options=[
      @clap.OptionArg("model", about=model_about()),
      @clap.OptionArg("user", short='u', about="user name"),
      @clap.OptionArg("host", short='H', about="host name"),
      @clap.OptionArg("os", short='o', about="OS"),
      @clap.OptionArg("device", short='d', about="device model"),
      @clap.OptionArg("kernel", short='k', about="kernel"),
      @clap.OptionArg("uptime", short='t', about="uptime hours,mins, e.g. 3,12"),
      @clap.OptionArg("shell", short='s', about="shell"),
      @clap.OptionArg(
        "resolution",
        short='r',
        about="resolution width,height, e.g. 3456,2234",
      ),
      @clap.OptionArg("de", short='e', about="desktop environment"),
      @clap.OptionArg("wm", short='w', about="window manager"),
      @clap.OptionArg("wm-theme", about="WM theme"),
      @clap.OptionArg("terminal", short='m', about="terminal"),
      @clap.OptionArg("term-font", about="terminal font"),
      @clap.OptionArg(
        "cpu",
        short='c',
        about="CPU name,cores,clock GHz, e.g. \"Apple M3 Max,16,4.05\"",
      ),
      @clap.OptionArg(
        "gpu",
        short='g',
        about="GPU name[,vram GB], e.g. \"Apple M3 Max\" or \"RTX 4090,24\"",
      ),
      @clap.OptionArg(
        "memory",
        short='M',
        about="memory used,total in GiB, e.g. 46.3,128",
      ),
      @clap.OptionArg("logo", short='l', about=logo_about()),
      @clap.OptionArg(
        "color",
        short='C',
        about="logo color: auto (use logo palette) or black, red, green, yellow, blue, magenta, cyan, white, none",
        default_values=["auto"],
      ),
    ],
  )
}

///|
fn model_about() -> String {
  let names = @fakefetch.all_models().map(m => m.name).join(", ")
  "device model: \{names} (default: \{@fakefetch.default_model_name()})"
}

///|
fn logo_about() -> String {
  let names = @fakefetch.all_logos.map(entry => entry.0).join(", ")
  "logo name: \{names}, none"
}