// Copyright (c) 2026 Yingjie Shang
// agent-telemetry is licensed under Mulan PSL v2.

///| Tool execution span helpers

///|
/// Start a span for a GenAI tool execution following OTel GenAI conventions.
///
/// Sets:
/// - `gen_ai.operation.name` = "execute_tool"
/// - `gen_ai.tool.name`
/// - `gen_ai.tool.call.arguments`
/// - `gen_ai.tool.call.id` (when provided)
/// - `gen_ai.tool.type` (when provided)
///
/// Span name: `execute_tool {name}`
pub fn start_tool_span(
  tracer : @trace.Tracer,
  name : String,
  arguments : String,
  /// The tool call identifier returned by the LLM.
  call_id? : String? = None,
  /// Type of the tool (e.g. "function", "extension", "datastore").
  tool_type? : String? = None,
  /// The parent span context to continue an existing trace.
  parent_context? : @context.Context = @context.Context::empty(),
) -> @trace.Span {
  let attributes = [
    @otel.KeyValue::new("gen_ai.operation.name", String("execute_tool")),
    @otel.KeyValue::new("gen_ai.tool.name", String(name)),
    @otel.KeyValue::new("gen_ai.tool.call.arguments", String(arguments)),
  ]
  match call_id {
    Some(id) =>
      attributes.push(@otel.KeyValue::new("gen_ai.tool.call.id", String(id)))
    None => ()
  }
  match tool_type {
    Some(t) =>
      attributes.push(@otel.KeyValue::new("gen_ai.tool.type", String(t)))
    None => ()
  }
  start_span(
    tracer,
    "execute_tool \{name}",
    kind=@trace.Internal,
    attributes~,
    parent_context~,
  )
}

///|
/// Set the result of a tool execution and mark the span as successful.
pub fn set_tool_result(span : @trace.Span, result : String) -> Unit {
  if result.contains("\"error\"") {
    span.set_status(
      @trace.Status::error(description=Some("tool returned error")),
    )
  } else {
    span.set_status(@trace.Status::ok())
  }
  span.set_attribute(
    @otel.KeyValue::new("gen_ai.tool.call.result", String(result)),
  )
}

///|
/// Mark a tool span as failed with a description.
pub fn set_tool_error(span : @trace.Span, description : String) -> Unit {
  span.set_status(@trace.Status::error(description=Some(description)))
  span.set_attribute(
    @otel.KeyValue::new("gen_ai.tool.call.result", String(description)),
  )
}