///|
fn usage() -> String {
  (
    #|MoonRobots Gate
    #|
    #|Usage:
    #|  moon run cmd/main -- decide  
    #|  moon run cmd/main -- lint [strict]
    #|  moon run cmd/main -- normalize [canonical|compact|annotated]
    #|  moon run cmd/main -- matrix
    #|  moon run cmd/main -- sitemap
    #|  moon run cmd/main -- plan
    #|  moon run cmd/main -- diff
    #|  moon run cmd/main -- audit [json]
    #|  moon run cmd/main -- stats
    #|
    #|Input:
    #|  MOONROBOTS_POLICY   Optional robots.txt text.
    #|  MOONROBOTS_SITEMAP Optional XML or text sitemap.
  )
}

///|
fn sample_policy() -> String {
  (
    #|User-agent: *
    #|Disallow: /private/
    #|Disallow: /admin/
    #|Allow: /private/public/
    #|Crawl-delay: 1.5
    #|
    #|User-agent: ResearchBot
    #|Disallow: /tmp/*.json$
    #|Allow: /tmp/public/
    #|
    #|Sitemap: https://example.com/sitemap.xml
  )
}

///|
fn sample_sitemap() -> String {
  (
    #|
    #|
    #|  
    #|    https://example.com/
    #|    2026-07-29
    #|    1.0
    #|  
    #|  
    #|    https://example.com/docs/guide
    #|    0.8
    #|  
    #|  
    #|    https://example.com/private/report
    #|    0.2
    #|  
    #|
  )
}

///|
fn policy_input() -> String {
  match @env.get_env_var("MOONROBOTS_POLICY") {
    Some(value) => value
    None => sample_policy()
  }
}

///|
fn sitemap_input() -> String {
  match @env.get_env_var("MOONROBOTS_SITEMAP") {
    Some(value) => value
    None => sample_sitemap()
  }
}

///|
fn command_decide(args : Array[String], policy : @gate.Policy) -> Unit {
  if args.length() < 4 {
    println("decide requires  and ")
    return
  }
  let decision = @gate.decide(policy, args[2], args[3])
  println(@gate.render_decision_trace(decision))
}

///|
fn command_lint(args : Array[String], policy : @gate.Policy) -> Unit {
  let options = if args.length() >= 3 && args[2] == "strict" {
    @gate.strict_lint_options()
  } else {
    @gate.default_lint_options()
  }
  let diagnostics = @gate.all_diagnostics_with_options(policy, options)
  println(@gate.render_policy_summary(policy))
  if diagnostics.length() == 0 {
    println("No diagnostics.")
  } else {
    println(@gate.render_diagnostics(diagnostics))
  }
}

///|
fn command_normalize(args : Array[String], policy : @gate.Policy) -> Unit {
  let style_name = if args.length() >= 3 { args[2] } else { "canonical" }
  match @gate.parse_render_style(style_name) {
    Ok(style) => println(@gate.render_policy(policy, style))
    Err(message) => {
      println(message)
      println("supported styles: canonical, compact, annotated")
    }
  }
}

///|
fn command_matrix(policy : @gate.Policy) -> Unit {
  let probes = @gate.build_probe_grid(
    ["GenericBot", "ResearchBot/2.0", "GPTBot"],
    ["/", "/docs/", "/admin/", "/private/report", "/private/public/readme"],
  )
  println(@gate.render_matrix_markdown(@gate.run_matrix(policy, probes)))
}

///|
fn command_sitemap(policy : @gate.Policy) -> Unit {
  let sitemap = @gate.parse_sitemap(sitemap_input())
  println(@gate.render_sitemap_summary(sitemap))
  println(@gate.render_blocked_sitemap_report(policy, "GenericBot", sitemap))
}

///|
fn command_plan(policy : @gate.Policy) -> Unit {
  let sitemap = @gate.parse_sitemap(sitemap_input())
  let tasks = @gate.tasks_from_sitemap(sitemap, 32768)
  let budget = @gate.crawl_budget(20, 1000000, 6, 10, 1000)
  let plan = @gate.plan_crawl(policy, "GenericBot", tasks, budget)
  println(@gate.render_crawl_plan(plan))
}

///|
fn command_diff(policy : @gate.Policy) -> Unit {
  let baseline = @gate.parse(
    (
      #|User-agent: *
      #|Disallow: /private/
      #|Allow: /private/public/
      #|Sitemap: https://example.com/old-sitemap.xml
    ),
  )
  let probes = @gate.build_probe_grid(["GenericBot", "ResearchBot"], [
    "/", "/admin/", "/private/report", "/private/public/readme",
  ])
  println(@gate.render_diff(@gate.diff_policies(baseline, policy, probes)))
}

///|
fn command_audit(args : Array[String]) -> Unit {
  let result = @gate.audit_default(policy_input())
  if args.length() >= 3 && args[2] == "json" {
    println(@gate.render_audit_json(result))
  } else {
    println(@gate.render_audit_markdown(result))
  }
}

///|
fn command_stats(policy : @gate.Policy) -> Unit {
  println(@gate.render_policy_summary(policy))
  println(
    "canonical characters: \{@gate.render_policy(policy, @gate.Canonical).length()}",
  )
  println("valid: \{policy.is_valid()}")
}

///|
fn main {
  let args = @env.args()
  if args.length() < 2 || args[1] == "--help" || args[1] == "-h" {
    println(usage())
    return
  }
  let policy = @gate.parse(policy_input())
  match args[1] {
    "decide" => command_decide(args, policy)
    "lint" => command_lint(args, policy)
    "normalize" => command_normalize(args, policy)
    "matrix" => command_matrix(policy)
    "sitemap" => command_sitemap(policy)
    "plan" => command_plan(policy)
    "diff" => command_diff(policy)
    "audit" => command_audit(args)
    "stats" => command_stats(policy)
    command => {
      println("Unknown command: \{command}")
      println(usage())
    }
  }
}