///|
pub(all) struct ApiEntry {
  name : String
  category : String
  description : String
} derive(Debug, ToJson)

///|
pub fn api_catalog() -> Array[ApiEntry] {
  [
    {
      name: "pic",
      category: "simulation",
      description: "particle-in-cell stepping and diagnostics",
    },
    {
      name: "vlasov",
      category: "simulation",
      description: "one-dimensional distribution advection",
    },
    {
      name: "poisson",
      category: "solver",
      description: "periodic and bounded electrostatic solves",
    },
    {
      name: "shapes",
      category: "deposition",
      description: "NGP, CIC, and TSC particle shapes",
    },
    {
      name: "profiles",
      category: "initialization",
      description: "deterministic spatial profiles",
    },
    {
      name: "species",
      category: "physics",
      description: "electron, proton, and ion descriptors",
    },
    {
      name: "diagnostics",
      category: "analysis",
      description: "moments, spectra, energy, and conservation",
    },
    {
      name: "benchmark",
      category: "reproducibility",
      description: "deterministic workload and result fingerprints",
    },
  ]
}

///|
pub fn api_catalog_categories() -> Array[String] {
  api_catalog().map(fn(entry) { entry.category })
}

///|
pub fn api_catalog_to_csv() -> String {
  let output = StringBuilder()
  output.write_string("name,category,description\n")
  for entry in api_catalog() {
    output.write_string(
      "\{entry.name},\{entry.category},\{entry.description}\n",
    )
  }
  output.to_string()
}

///|
pub fn api_catalog_contains(name : String) -> Bool {
  api_catalog().any(fn(entry) { entry.name == name })
}

///|
pub fn public_api_summary() -> String {
  "moonbit-plasma public modules: \{api_catalog().length()}\n\{api_catalog_to_csv()}"
}

///|
pub fn cli_help() -> String {
  "moon run cmd/main\n\nOutputs deterministic benchmark CSV for the standard PIC scenarios.\nUse the library APIs for custom grids, species, shapes, boundaries, and diagnostics.\n"
}