// Copyright 2026 Cloudflavor GmbH

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Tool calling example
//!
//! This example demonstrates how to use the ollama-api-rs with tool calling
//! capabilities for function calling.

use oai_sdk::{ChatRequest, Message, ModelClient, Tool, ToolFunction};
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create the client
    let client = ModelClient::builder()
        .base_url("http://localhost:11434")
        .build()?;

    println!("Ollama Client Tool Calling Example");
    println!("This example shows how to use tool calling with the Ollama API.\n");

    // Define a tool for getting weather information
    let tools = vec![Tool {
        tool_type: "function".to_string(),
        function: ToolFunction {
            name: "get_current_weather".to_string(),
            description: "Get the current weather for a location".to_string(),
            parameters: json!({
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The location to get the weather for, e.g. San Francisco, CA"
                    },
                    "format": {
                        "type": "string",
                        "description": "The format to return the weather in, e.g. 'celsius' or 'fahrenheit'",
                        "enum": ["celsius", "fahrenheit"]
                    }
                },
                "required": ["location", "format"]
            }),
        },
    }];

    // Create a chat request with tools
    let messages = vec![Message::user("What is the weather like in Tokyo?")];

    let request = ChatRequest {
        model: "llama3.1:8b".to_string(), // Make sure this model supports tool calling
        messages,
        stream: false,
        format: None,
        options: None,
        keep_alive: None,
        tools: Some(tools),
        think: None,
    };

    println!("User: What is the weather like in Tokyo?");

    match client.chat(request).await {
        Ok(response) => {
            if let Some(tool_calls) = response.message.tool_calls {
                println!("Model wants to call tools:");
                for tool_call in tool_calls {
                    println!("  - Function: {}", tool_call.function.name);
                    println!(
                        "    Arguments: {}",
                        serde_json::to_string_pretty(&tool_call.function.arguments)?
                    );
                }

                // In a real application, you would execute the tool calls here
                // and then send the results back to the model
                println!("\nIn a real application, you would execute these tool calls");
                println!("and send the results back to the model for a final response.");
            } else {
                println!("Assistant: {}", response.message.content);
            }
        }
        Err(e) => {
            println!("Error: {}", e);
        }
    }

    Ok(())
}
