///|
/// ═══ 功能组:pipeline(编码解码编排)═══
/// 本文件:Prism 门面内部方法(encode/decode 样板)。
/// 通用 source→target 管线见 codec_pipeline.mbt。

///|
/// SDK request/response/stream conversion pipeline (internal implementation)

///|
/// 从文本和选项构建 LucentRequest(消除 3 处重复的 Context→model→request 样板)
fn build_request_from_text(
  text : String,
  opts : PrismOptions,
) -> @lux.LucentRequest {
  let ctx = Context::new().add_user(text)
  let model = opts.model.unwrap_or(DEFAULT_MODEL)
  context_to_lux_request(ctx, model, opts)
}

///|
/// 将提供商 JSON 解码为 LucentResponse(基于 ProviderRegistration 注册表)
fn Prism::decode_to_lux(
  self : Prism,
  json_str : String,
) -> Result[@lux.LucentResponse, String] {
  match match_provider_name(self.provider) {
    Some(reg) =>
      match (reg.response_decode)(json_str) {
        Ok(cr) => Ok(cr.value())
        Err(e) => Err(e)
      }
    None => Err("unknown provider: " + self.provider)
  }
}

///|
/// 编码 LucentRequest 为提供商 JSON(基于 ProviderRegistration 注册表)
fn Prism::encode_lux_request(
  self : Prism,
  req : @lux.LucentRequest,
) -> Result[String, String] {
  match match_provider_name(self.provider) {
    Some(reg) =>
      match (reg.request_encode)(req) {
        Ok(cr) => Ok(cr.value())
        Err(e) => Err(e)
      }
    None => Err("unknown provider: " + self.provider)
  }
}

///|
/// 将提供商 SSE 解码为原始 LucentStreamEvent(基于注册表)
fn decode_sse_inner(
  provider : String,
  sse_str : String,
) -> Result[Array[@lux.LucentStreamEvent], String] {
  match match_provider_name(provider) {
    Some(reg) =>
      match (reg.events_decode)(sse_str) {
        Ok(cr) => Ok(cr.value())
        Err(e) => Err(e)
      }
    None => Err("unknown provider: " + provider)
  }
}

///|
/// 发射一个完整 ToolCall PrismEvent(工具块冲刷共用)
fn push_tool_call_event(
  result : Array[PrismEvent],
  id : String,
  name : String,
  arguments_json : String,
) -> Unit {
  result.push(ToolCall({ id, name, arguments_json, }))
}

///|
/// 将 LucentStreamEvent 数组转为 PrismEvent 数组(SDK 内部)
///
/// 工具调用累积状态机(覆盖三家 provider 的流形态):
/// - openai/messages:BlockStart(ToolCall(id,name)) → BlockDelta(ToolArgumentsDelta)
///   → BlockEnd(idx)
/// - responses:ItemStart(idx, ToolCall 骨架) → BlockDelta(ToolArgumentsDelta)
///   → BlockEnd(idx)(两者同一 output_index 空间)
/// 块结束(或流尾)时发射完整 ToolCall 事件,含累积后的 arguments_json。
/// 修复记录:此前只消费 ItemStart,openai/messages 的 BlockStart/BlockDelta
/// 路径无人处理——默认 provider 的流式 tool call 被完全静默丢弃。
fn lucent_events_to_prism(
  events : Array[@lux.LucentStreamEvent],
) -> Array[PrismEvent] {
  let result : Array[PrismEvent] = []
  let mut has_finish = false
  // 当前 tool 块累积状态
  let mut tool_active = false
  let mut tool_idx : Int = -1
  let mut tool_id : String = ""
  let mut tool_name : String = ""
  let mut tool_args : String = ""
  for ev in events {
    if has_finish {
      break
    }
    match ev {
      BlockDelta(_, TextDelta(s)) => result.push(TextDelta(s))
      BlockStart(idx, ToolCall(id, name)) => {
        if tool_active {
          push_tool_call_event(result, tool_id, tool_name, tool_args)
        }
        tool_active = true
        tool_idx = idx
        tool_id = id
        tool_name = name
        tool_args = ""
      }
      BlockStart(_, _) =>
        // 非 tool 块开始:冲刷未闭合 tool 块
        if tool_active {
          push_tool_call_event(result, tool_id, tool_name, tool_args)
          tool_active = false
          tool_args = ""
        }
      BlockDelta(idx, ToolArgumentsDelta(s)) =>
        if tool_active && idx == tool_idx {
          tool_args = tool_args + s
        }
      BlockEnd(idx) =>
        if tool_active && idx == tool_idx {
          push_tool_call_event(result, tool_id, tool_name, tool_args)
          tool_active = false
          tool_args = ""
        }
      BlockDiscard(idx) =>
        // Gemini 全量帧覆盖:丢弃该块(不发射 ToolCall)
        if tool_active && idx == tool_idx {
          tool_active = false
          tool_args = ""
        }
      ItemStart(idx, ToolCall(tu)) => {
        // responses 路径:骨架开启 tool 块(arguments 可能已在骨架中)
        if tool_active {
          push_tool_call_event(result, tool_id, tool_name, tool_args)
        }
        tool_active = true
        tool_idx = idx
        tool_id = tu.id
        tool_name = tu.name
        tool_args = tu.arguments_json
      }
      ItemStart(_, ToolResult(tr)) =>
        result.push(
          ToolResult({
            tool_use_id: tr.tool_use_id,
            content: @lux.lucent_content_to_text(tr.content),
            is_error: tr.is_error,
          }),
        )
      ItemStart(_, _) =>
        // 新 item 开始:冲刷未闭合 tool 块
        if tool_active {
          push_tool_call_event(result, tool_id, tool_name, tool_args)
          tool_active = false
          tool_args = ""
        }
      BlockDelta(_, ThinkingDelta(s)) =>
        result.push(Thinking({ text: s, signature: None, redacted: false, }))
      Finish(fr) => {
        let pfr = match fr {
          Stop => Stop
          Length => Length
          ToolCalls => ToolCalls
          ContentFilter => ContentFilter
          _ => Error
        }
        result.push(Finish(pfr))
        has_finish = true
      }
      _ => ()
    }
  }
  // 流尾冲刷:未闭合的 tool 块也要发射,避免静默丢失
  if tool_active {
    push_tool_call_event(result, tool_id, tool_name, tool_args)
  }
  result
}