// Demo: Simulate an Agent conversation with nested spans

fn call_web_search(query : String) -> String raise Failure {
  @trace.span("tool.web_search", Some("{\"query\": \"" + query + "\"}"), () => {
    @trace.add_event("http_request", Some("GET /search?q=" + query))
    let result = "[{\"title\": \"MoonBit Guide\", \"snippet\": \"A fast language for reliable agents.\"}]"
    @trace.add_event("http_response", Some("200 OK"))
    result
  })
}

fn call_calculator(a : Int, b : Int) -> Int raise Failure {
  @trace.span("tool.calculator", Some("{\"a\": \{a}, \"b\": \{b}}"), () => {
    @trace.add_event("compute", Some("adding \{a} + \{b}"))
    a + b
  })
}

fn call_failing_tool() -> String raise Failure {
  @trace.span("tool.knowledge_base", Some("{\"query\": \"unknown topic\"}"), () => {
    @trace.add_event("search", Some("querying vector store..."))
    raise Failure("Knowledge base timeout after 5000ms")
  })
}

fn agent_think(user_input : String) -> String raise Failure {
  @trace.span("agent_think", Some("{\"input\": \"" + user_input + "\"}"), () => {
    @trace.add_event("reasoning", Some("Analyzing user intent..."))
    @trace.set_metadata("model", "gpt-4o")
    @trace.set_metadata("tokens", "156")
    "I need to search the documentation and do a calculation"
  })
}

fn handle_user_message(user_input : String) -> String raise Failure {
  @trace.span("handle_user_message", Some("{\"user\": \"" + user_input + "\"}"), () => {
    let _plan = agent_think(user_input)

    // Tool call 1: retrieve context for the agent
    let search_result = call_web_search("MoonBit agent observability")

    // Tool call 2: calculator
    let calc_result = call_calculator(42, 58)

    // Tool call 3: will fail (demonstrates error capture, handled gracefully)
    let kb_result = try {
      call_failing_tool()
    } catch {
      Failure(_) => "knowledge base unavailable (handled gracefully)"
    }

    let answer = "Research: \{search_result}, Calc: \{calc_result}, KB: \{kb_result}"
    answer
  })
}

fn main raise Failure {
  println("=== MoonTrace Phase 1 Demo ===\n")

  let trace_id = @trace.start_trace()
  println("Started trace: \{trace_id}\n")

  let answer = handle_user_message("How can I observe a MoonBit agent and what is 42+58?")
  println("Agent answer: \{answer}\n")

  let trace = @trace.end_trace()

  match trace {
    None => println("No trace found!")
    Some(t) => @trace.print_trace(t)
  }

  println("\n=== Phase 1 complete ===")
}