//! Examples demonstrating the `#[tool]` procedural macro.
//!
//! The macro eliminates boilerplate for defining tools:
//! Instead of manually building `ToolDefinition` + `ToolSchema` + serde structures,
//! you write a typed Rust function and derive everything automatically.
//!
//! # Manual way (without macro)
//!
//! ```
//! use agent::{ToolDefinition, ToolParam, ToolRegistry, ToolSchema};
//! use serde_json::json;
//!
//! fn register_manual(registry: &mut ToolRegistry) {
//!     registry.register_fn("search_issues", |_ctx, args| {
//!         async move {
//!             let args: serde_json::Value = args;
//!             let title = args["title"].as_str().unwrap_or("");
//!             Ok(json!([{ "title": title, "status": "open" }]))
//!         }.boxed()
//!     });
//! }
//! ```
//!
//! # With `#[tool]` macro (recommended)
//!
//! ```
//! use agent_tool_derive::tool;
//! use agent::{ToolDefinition, ToolRegistry, ToolError};
//!
//! #[tool(description = "Search issues by title", params(
//!     title = "Issue title to search for",
//!     status = "Filter by status (open/closed/all)"
//! ))]
//! async fn search_issues(
//!     title: String,
//!     status: Option<String>,
//! ) -> Result<Vec<serde_json::Value>, String> {
//!     Ok(vec![serde_json::json!({
//!         "title": title,
//!         "status": status.unwrap_or_else(|| "open".to_string())
//!     })])
//! }
//!
//! fn register_with_macro(registry: &mut ToolRegistry) {
//!     register_search_issues(registry); // Generated by #[tool]
//! }
//! ```
//!
//! The macro generates:
//! - `SearchIssuesParameters` struct (serde Deserialize)
//! - `SEARCH_ISSUES_DEFINITION: ToolDefinition` constant
//! - `register_search_issues(registry: &mut ToolRegistry)` helper

#[cfg(test)]
mod tests {
    use crate::{ToolError, ToolRegistry};

    // Example: using the manual approach (without macro)
    // This demonstrates the baseline — how it looks without #[tool]
    #[test]
    fn manual_tool_registration_shows_boilerplate() {
        use futures::FutureExt;

        let mut registry = ToolRegistry::new();
        registry.register_fn("echo", |_ctx, args| {
            async move {
                let text: serde_json::Value = serde_json::from_value(args)
                    .map_err(|e| ToolError::ParseError(e.to_string()))?;
                Ok(text)
            }
            .boxed()
        });
        assert_eq!(registry.len(), 1);
        assert!(registry.get("echo").is_some());
    }

    // NOTE: To use #[tool], the `agent-tool-derive` crate must be a dependency.
    // Since proc-macro crates cannot be conditionally compiled via cfg_attr,
    // the macro usage example is documented above in the module doc comment.
    //
    // Full working example (requires agent-tool-derive dependency):
    //
    // ```ignore
    // use agent_tool_derive::tool;
    //
    // #[tool(description = "Echo back the input text", params(
    //     text = "The text to echo back"
    // ))]
    // async fn echo(text: String) -> Result<String, String> {
    //     Ok(text)
    // }
    //
    // #[test]
    // fn test_macro_generates_definition() {
    //     let def = ECHO_DEFINITION;
    //     assert_eq!(def.name, "echo");
    //     assert!(def.description.is_some());
    //     assert!(def.parameters.is_some());
    //
    //     let schema = def.parameters.unwrap();
    //     assert_eq!(schema.schema_type, "object");
    //     let props = schema.properties.unwrap();
    //     assert!(props.contains_key("text"));
    // }
    //
    // #[test]
    // fn test_macro_registers_tool() {
    //     let mut registry = ToolRegistry::new();
    //     register_echo(&mut registry);
    //     assert!(registry.get("echo").is_some());
    // }
    // ```
}
