#pragma once

#include <nlohmann/json.hpp>
#include <string>
#include <map>
#include <functional>
#include <memory>

namespace celuna {

using json = nlohmann::json;

/**
 * @brief Function signature for tool handlers
 *
 * @param input Tool input arguments
 * @return JSON result to send back to LLM
 */
using ToolHandler = std::function<json(const json& input)>;

/**
 * @brief Tool definition with metadata and handler
 */
struct ToolDefinition {
    std::string name;
    std::string description;
    json input_schema;
    ToolHandler handler;
};

/**
 * @brief Registry for tools available to the LLM
 *
 * Tools are functions that the LLM can call to interact with the system.
 * Each tool has:
 * - name: Unique identifier
 * - description: What the tool does (for LLM)
 * - input_schema: JSON Schema for parameters
 * - handler: Function to execute
 */
class ToolRegistry {
public:
    ToolRegistry() = default;

    /**
     * @brief Register a new tool
     */
    void registerTool(const std::string& name,
                     const std::string& description,
                     const json& inputSchema,
                     ToolHandler handler);

    /**
     * @brief Register a tool from a definition struct
     */
    void registerTool(const ToolDefinition& tool);

    /**
     * @brief Execute a tool by name
     *
     * @param name Tool name
     * @param input Tool arguments
     * @return JSON result
     */
    json execute(const std::string& name, const json& input);

    /**
     * @brief Get tool definitions for LLM
     *
     * @return Array of tool definitions in provider-agnostic format
     */
    json getToolDefinitions() const;

    /**
     * @brief Check if a tool exists
     */
    bool hasTool(const std::string& name) const;

    /**
     * @brief Get number of registered tools
     */
    size_t size() const { return m_tools.size(); }

private:
    std::map<std::string, ToolDefinition> m_tools;
};

} // namespace celuna
