///|
let old_checkout : String =
  #|contract Checkout 1.0.0
  #|type Order closed
  #|field id string required minlen=1
  #|field total int required min=0 max=100000
  #|field status enum:pending|paid|failed required
  #|field note string optional maxlen=200
  #|end

///|
let new_checkout : String =
  #|contract Checkout 2.0.0
  #|type Order closed
  #|field id string required minlen=8
  #|field total int required min=1 max=100000
  #|field status enum:pending|paid required
  #|field note string required maxlen=80
  #|field currency string required minlen=3 maxlen=3
  #|end

///|
fn parse_mode(value : String) -> @evo.CompatibilityMode? {
  match value {
    "backward" => Some(@evo.Backward)
    "forward" => Some(@evo.Forward)
    "full" => Some(@evo.Full)
    _ => None
  }
}

///|
fn print_report(report : @evo.AnalysisReport, format : String) -> Unit {
  match format {
    "json" => println(report.to_json())
    "sarif" => println(report.to_sarif())
    "witness-json" => println(report.to_witness_json())
    "witness-jsonl" => println(report.to_witness_jsonl())
    "witness-md" => println(report.to_witness_markdown())
    "score-json" => println(report.score_witness_evidence().to_json())
    "score-md" => println(report.score_witness_evidence().to_markdown())
    "replay-json" => println(report.to_replay_json())
    "replay-md" => println(report.to_replay_markdown())
    "replay-checklist" => println(report.to_replay_checklist())
    _ => println(report.to_markdown())
  }
}

///|
fn run_demo(format : String) -> Unit {
  match @evo.analyze_text(old_checkout, new_checkout, mode=@evo.Full) {
    Ok(report) => print_report(report, format)
    Err(error) => println("error: " + error.render())
  }
}

///|
fn print_help() -> Unit {
  let help_text =
    #|EvoWitness — explain versioned payload compatibility with minimal counterexamples
    #|
    #|Usage:
    #|  evowitness demo [markdown|json|sarif|witness-json|witness-jsonl|witness-md|score-json|score-md|replay-json|replay-md|replay-checklist]
    #|  evowitness compare    [markdown|json|sarif|witness-json|witness-jsonl|witness-md|score-json|score-md|replay-json|replay-md|replay-checklist]
    #|
    #|For compare, replace line breaks in each contract with semicolons.
    #|Example contract: contract C 1;type Item closed;field id string required;end
  println(help_text)
}

///|
fn main {
  let argv = @env.args()
  let args = if argv.length() > 0 { argv[1:] } else { argv[:] }
  if args.is_empty() {
    run_demo("markdown")
    return
  }
  match args[0] {
    "demo" => run_demo(if args.length() >= 2 { args[1] } else { "markdown" })
    "compare" => {
      if args.length() < 4 {
        print_help()
        return
      }
      guard parse_mode(args[1]) is Some(mode) else {
        println("error: mode must be backward, forward, or full")
        return
      }
      let old_source = args[2].replace_all(old=";", new="\n")
      let new_source = args[3].replace_all(old=";", new="\n")
      let format = if args.length() >= 5 { args[4] } else { "markdown" }
      match @evo.analyze_text(old_source, new_source, mode~) {
        Ok(report) => print_report(report, format)
        Err(error) => println("error: " + error.render())
      }
    }
    "help" | "--help" | "-h" => print_help()
    _ => print_help()
  }
}