#include "ToolRegistry.hpp"
#include <spdlog/spdlog.h>

namespace celuna {

void ToolRegistry::registerTool(const std::string& name,
                                const std::string& description,
                                const json& inputSchema,
                                ToolHandler handler) {
    ToolDefinition tool;
    tool.name = name;
    tool.description = description;
    tool.input_schema = inputSchema;
    tool.handler = handler;
    registerTool(tool);
}

void ToolRegistry::registerTool(const ToolDefinition& tool) {
    m_tools[tool.name] = tool;
    spdlog::debug("Registered tool: {}", tool.name);
}

json ToolRegistry::execute(const std::string& name, const json& input) {
    auto it = m_tools.find(name);
    if (it == m_tools.end()) {
        spdlog::warn("Unknown tool called: {}", name);
        return {
            {"error", "unknown_tool"},
            {"message", "Tool not found: " + name}
        };
    }

    try {
        spdlog::debug("Executing tool: {} with input: {}", name, input.dump().substr(0, 100));
        json result = it->second.handler(input);
        return result;
    } catch (const std::exception& e) {
        spdlog::error("Tool {} threw exception: {}", name, e.what());
        return {
            {"error", "execution_failed"},
            {"message", e.what()}
        };
    }
}

json ToolRegistry::getToolDefinitions() const {
    json tools = json::array();

    for (const auto& [name, tool] : m_tools) {
        tools.push_back({
            {"name", tool.name},
            {"description", tool.description},
            {"input_schema", tool.input_schema}
        });
    }

    return tools;
}

bool ToolRegistry::hasTool(const std::string& name) const {
    return m_tools.find(name) != m_tools.end();
}

} // namespace celuna
