// The command table. `mctl help` prints it, `mctl completion` completes from it and
// the README lists it, so there is one description of every command and no second
// place for one to fall out of date.

///|
/// One command: what it is called, the line that shows how to call it, and one
/// sentence saying what it does.
pub(all) struct Command {
  name : String
  usage : String
  summary : String
}

///|
/// Every command mctl accepts, in the order `help` prints them: the generators, the
/// scaffolds, the spec tools, then the housekeeping.
pub fn commands() -> Array[Command] {
  [
    {
      name: "gen",
      usage: "mctl gen  ",
      summary: "generate a project tree, models or a document from a spec",
    },
    {
      name: "api",
      usage: "mctl api  ",
      summary: "work on a .api spec itself: format it, check it, document it, or generate a client",
    },
    {
      name: "model",
      usage: "mctl model  …",
      summary: "read a schema — DDL, a live database, a spec — and write moonorm models",
    },
    {
      name: "gateway",
      usage: "mctl gateway ",
      summary: "scaffold an HTTP gateway that fronts a moonrpc service",
    },
    {
      name: "migrate",
      usage: "mctl migrate ",
      summary: "write the SQL migrations a spec's models imply",
    },
    {
      name: "quickstart",
      usage: "mctl quickstart ",
      summary: "scaffold, generate and build a service in one step",
    },
    {
      name: "template",
      usage: "mctl template  [name]",
      summary: "list the bundled template library, or write one into a directory",
    },
    {
      name: "upgrade",
      usage: "mctl upgrade [version]",
      summary: "move the moonbitstack pins in moon.mod to a release",
    },
    {
      name: "config",
      usage: "mctl config  [key] [value]",
      summary: "read and write the mctl configuration file",
    },
    {
      name: "completion",
      usage: "mctl completion ",
      summary: "print a shell completion script for mctl",
    },
    {
      name: "bug",
      usage: "mctl bug [title]",
      summary: "print a bug report pre-filled with the environment",
    },
    {
      name: "env",
      usage: "mctl env",
      summary: "show the configuration mctl would use and where it came from",
    },
    {
      name: "docker",
      usage: "mctl docker ",
      summary: "write a Dockerfile and .dockerignore for a service",
    },
    {
      name: "kube",
      usage: "mctl kube ",
      summary: "write deployment and service manifests for a service",
    },
    {
      name: "plugin",
      usage: "mctl plugin  ",
      summary: "run an external plugin over a spec, reading and writing JSON",
    },
    { name: "help", usage: "mctl help", summary: "print this message", },
  ]
}

///|
/// The words a shell should complete at the first position.
pub fn command_names() -> Array[String] {
  let out : Array[String] = []
  for c in commands() {
    out.push(c.name)
  }
  out
}

///|
/// The second word of a command that takes a sub-command, for a completion script
/// that completes two levels deep.
pub fn subcommands(name : String) -> Array[String] {
  match name {
    "gen" => ["api", "rpc", "model", "crud", "doc", "gql", "agent"]
    "api" => ["format", "validate", "doc", "ts", "dart", "kt", "java", "new"]
    "model" => ["new", "datasource", "mysql", "pg", "mongo", "cache"]
    "rpc" => ["new"]
    "gql" => ["new"]
    "mcp" => ["new"]
    "template" => ["list", "show", "init"]
    "config" => ["list", "get", "set", "path", "migrate"]
    "completion" => ["bash", "zsh", "fish", "powershell"]
    _ => []
  }
}

///|
/// The `mctl help` page: what mctl is, then one line per command, then the flags
/// every generator shares.
pub fn usage_text(version : String) -> String {
  let out : Array[String] = []
  out.push(
    "mctl " +
    version +
    " — a spec-driven generator for MoonBit services (← goctl)",
  )
  out.push("")
  out.push("usage:")
  let width = 34
  for c in commands() {
    out.push("  " + pad(c.usage, width) + c.summary)
  }
  out.push("")
  out.push("flags:")
  out.push(
    "  " +
    pad("--home ", width) +
    "use this template home instead of the bundled library",
  )
  out.push(
    "  " +
    pad("--remote ", width) +
    "read the template library from this git remote",
  )
  out.push(
    "  " +
    pad("--branch ", width) +
    "the branch of --remote to read (default: main)",
  )
  out.push(
    "  " +
    pad("--style