// The `agent` generator: scaffold a moonkoog agent from a `.api` spec — each
// service operation becomes an agent `Tool`, assembled into an `AIAgent`. goctl
// has no agent target; this is the moon-heke suite extending mctl to scaffold its
// agent layer (moonkoog). The output compiles against `Lfan-ke/moonkoog`.

///|
/// Generate a moonkoog agent scaffold from `spec`. Every route becomes a `Tool`
/// whose descriptor advertises the operation (a single string `input` parameter to
/// fill out) and whose `execute_raw` is a stub, and `build_agent` assembles them
/// into an `AIAgent` with the service's name in its system prompt. The output
/// compiles against `Lfan-ke/moonkoog`; fill in each `execute_raw` to make it run.
pub fn generate_agent(spec : Spec) -> String {
  let mut out = "// Code generated by moonctl. DO NOT EDIT.\n\n"
  for r in spec.routes {
    let type_name = to_pascal(r.handler) + "Tool"
    out = out +
      "///|\n/// A tool wrapping the `" +
      r.handler +
      "` operation (" +
      r.verb +
      " " +
      r.path +
      ").\npriv struct " +
      type_name +
      " {}\n\n"
    out = out +
      "///|\nimpl @tools.Tool for " +
      type_name +
      " with fn descriptor(_self) {\n" +
      "  {\n    name: \"" +
      r.handler +
      "\",\n    description: \"" +
      r.verb +
      " " +
      r.path +
      "\",\n    required_parameters: [\n" +
      "      { name: \"input\", description: \"operation input\", ptype: @tools.TString },\n" +
      "    ],\n    optional_parameters: [],\n  }\n}\n\n"
    out = out +
      "///|\nimpl @tools.Tool for " +
      type_name +
      " with fn execute_raw(_self, args) {\n  let _ = args\n  \"TODO: implement " +
      r.handler +
      "\"\n}\n\n"
  }
  out = out +
    "///|\n/// Assemble the `" +
    spec.service +
    "` agent: the service's operations exposed as tools.\n" +
    "pub fn build_agent(\n  executor : &@agent.LLMClient,\n  model : @llm.LLModel,\n) -> @agent.AIAgent {\n" +
    "  let registry = @tools.ToolRegistry::new()"
  for r in spec.routes {
    out = out + "\n    .add(" + to_pascal(r.handler) + "Tool::{  })"
  }
  out = out +
    "\n  @agent.AIAgent::new(\n    executor,\n    model=model,\n    tool_registry=registry,\n    system_prompt=Some(\"You are the " +
    spec.service +
    " assistant.\"),\n  )\n}\n"
  out
}