///|
fn usage() -> String {
  (
    #|MoonAnsi Guard command-line audit tool
    #|
    #|Usage:
    #|  moon run cmd/audit -- [options] 
    #|
    #|Options:
    #|  --escaped       Decode \e, \a, \r, \n, \t, \b and \\ in input
    #|  --styled        Preserve SGR color and emphasis sequences
    #|  --clean-only    Print sanitized text without the audit report
    #|  --json          Print a machine-readable JSON report
    #|  --redacted      Remove captured payloads from reports
    #|  --strict-gate   Apply conservative CI decision thresholds
    #|  --permissive-gate
    #|                  Apply trusted-terminal decision thresholds
    #|  --help          Show this help
    #|
    #|Examples:
    #|  moon run cmd/audit -- "plain build log"
    #|  moon run cmd/audit -- --escaped "ok\e]52;c;secret\aend"
  )
}

///|
fn decode_escaped(input : String) -> String {
  let chars = input.to_array()
  let output : Array[Char] = []
  let mut index = 0
  while index < chars.length() {
    if chars[index] == '\\' && index + 1 < chars.length() {
      let next = chars[index + 1]
      if next == 'e' {
        output.push('\u{1b}')
        index = index + 2
      } else if next == 'a' {
        output.push('\u{07}')
        index = index + 2
      } else if next == 'r' {
        output.push('\r')
        index = index + 2
      } else if next == 'n' {
        output.push('\n')
        index = index + 2
      } else if next == 't' {
        output.push('\t')
        index = index + 2
      } else if next == 'b' {
        output.push('\b')
        index = index + 2
      } else if next == '\\' {
        output.push('\\')
        index = index + 2
      } else {
        output.push(chars[index])
        index = index + 1
      }
    } else {
      output.push(chars[index])
      index = index + 1
    }
  }
  String::from_array(output)
}

///|
fn join_text(parts : Array[String]) -> String {
  let mut text = ""
  for index, part in parts {
    if index > 0 {
      text = text + " "
    }
    text = text + part
  }
  text
}

///|
fn main {
  let args = @env.args()
  let text_parts : Array[String] = []
  let mut escaped = false
  let mut styled = false
  let mut clean_only = false
  let mut json = false
  let mut redacted = false
  let mut strict_gate = false
  let mut permissive_gate = false
  let mut show_help = false
  for index = 1; index < args.length(); index = index + 1 {
    let arg = args[index]
    if arg == "--escaped" {
      escaped = true
    } else if arg == "--styled" {
      styled = true
    } else if arg == "--clean-only" {
      clean_only = true
    } else if arg == "--json" {
      json = true
    } else if arg == "--redacted" {
      redacted = true
    } else if arg == "--strict-gate" {
      strict_gate = true
    } else if arg == "--permissive-gate" {
      permissive_gate = true
    } else if arg == "--help" || arg == "-h" {
      show_help = true
    } else {
      text_parts.push(arg)
    }
  }
  if show_help || text_parts.length() == 0 {
    println(usage())
    return
  }
  let raw = join_text(text_parts)
  let input = if escaped { decode_escaped(raw) } else { raw }
  let policy = if styled {
    @guard.Policy::styled()
  } else {
    @guard.Policy::strict()
  }
  let result = @guard.scan_with_policy(input, policy)
  if clean_only {
    println(result.text())
  } else if json {
    let report_policy = if redacted {
      @guard.ReportPolicy::redacted()
    } else {
      @guard.ReportPolicy::full()
    }
    println(result.json_report_with(report_policy))
  } else if redacted {
    println(result.redacted_audit_report())
  } else {
    println(result.audit_report())
    let gate = if permissive_gate {
      @guard.GatePolicy::permissive()
    } else if strict_gate {
      @guard.GatePolicy::strict()
    } else {
      @guard.GatePolicy::balanced()
    }
    println("configured gate: \{result.decide_with(gate).label()}")
    for reason in result.decision_reasons(gate) {
      println("- \{reason}")
    }
  }
}