// 离线回放工具:把一段 JSON 文本按固定字节大小分块喂入解析器,
// 打印每个块产生的事件与最终完整性判断。
//
// 用法(native):
//   moon run --target native cmd/replay
//   moon run --target native cmd/replay -- '{"a":1}' 3
//
// 不联网、不调用模型:样本来自命令行或内置常量,因此可重复复现。

///|
/// 内置样本:一条典型的工具调用参数流。
fn default_sample() -> String {
  "{\"tool\":\"create_ticket\",\"args\":{\"title\":\"登录失败\",\"priority\":3,\"tags\":[\"bug\",\"p1\"],\"meta\":{\"ratio\":0.125,\"ok\":true,\"note\":null}}}"
}

///|
/// 解析块大小;非法输入回退到 8。
fn parse_chunk_size(text : String) -> Int {
  try {
    let size = @str.parse_int(text)
    if size > 0 {
      size
    } else {
      8
    }
  } catch {
    _ => 8
  } noraise {
    size => size
  }
}

///|
/// 解析命令行参数:`[程序名, 文本?, 块大小?]`。
fn parse_args() -> (String, Int) {
  let args = @env.args()
  let source = match args.get(1) {
    Some(text) => text
    None => default_sample()
  }
  let chunk_size = match args.get(2) {
    Some(text) => parse_chunk_size(text)
    None => 8
  }
  (source, chunk_size)
}

///|
/// 打印一个块产生的事件。
fn print_events(events : Array[@moonstream.Event]) -> Unit {
  for event in events {
    match event {
      @moonstream.Event::ObjectBegin(path~, ..) =>
        println("  {  \{path.to_string()}")
      @moonstream.Event::ObjectEnd(path~, ..) =>
        println("  }  \{path.to_string()}")
      @moonstream.Event::ArrayBegin(path~, ..) =>
        println("  [  \{path.to_string()}")
      @moonstream.Event::ArrayEnd(path~, ..) =>
        println("  ]  \{path.to_string()}")
      @moonstream.Event::KeyComplete(name~, ..) => println("  key   \{name}")
      @moonstream.Event::StringDelta(path~, text~, ..) =>
        println("  delta \{path.to_string()} = \{text}")
      @moonstream.Event::ValueComplete(path~, value~, ..) =>
        println("  value \{path.to_string()} = \{render_value(value)}")
    }
  }
}

///|
/// 叶值的可读文本。
fn render_value(value : @moonstream.LeafValue) -> String {
  match value {
    @moonstream.LeafValue::Null => "null"
    @moonstream.LeafValue::Bool(b) => b.to_string()
    @moonstream.LeafValue::Number(n) => n.lexeme()
    @moonstream.LeafValue::String(s) => "\"" + s + "\""
  }
}

///|
/// 打印最终结果。
fn print_result(result : @moonstream.FinishResult) -> Unit {
  match result {
    @moonstream.FinishResult::Completed(doc) =>
      println("结果: Completed,共 \{doc.byte_length()} 字节")
    @moonstream.FinishResult::Incomplete(pos~, expected~) =>
      println("结果: Incomplete(位置 \{pos},期待 \{expected})")
    @moonstream.FinishResult::Aborted(reason~) =>
      println("结果: Aborted(\{Debug::to_repr(reason)})")
  }
}

///|
fn main {
  let (source, chunk_size) = parse_args()
  let bytes = @utf8.encode(source)
  println("输入: \{bytes.length()} 字节,分块大小 \{chunk_size}")
  // 默认限制不可能非法,这里的 try! 只在不可达情况下终止。
  let parser = try! @moonstream.Parser::new()
  let mut index = 0
  let mut block = 0
  while index < bytes.length() {
    let end = if index + chunk_size > bytes.length() {
      bytes.length()
    } else {
      index + chunk_size
    }
    let chunk = Bytes::from_array(bytes[index:end].to_array())
    block = block + 1
    println("块 \{block}(字节 \{index}..\{end})")
    let fed = Ok(parser.feed(chunk)) catch { err => Err(err) }
    match fed {
      Ok(events) => print_events(events)
      Err(err) => {
        println("解析错误: \{Debug::to_repr(err)}")
        return
      }
    }
    index = end
  }
  let finished = Ok(parser.finish()) catch { err => Err(err) }
  match finished {
    Ok((tail, result)) => {
      if tail.length() > 0 {
        println("收尾事件")
        print_events(tail)
      }
      print_result(result)
    }
    Err(err) => println("解析错误: \{Debug::to_repr(err)}")
  }
}