/**
 * @file mcp_server.h
 * @brief MCP Server implementation
 * 
 * This file implements the server-side functionality for the Model Context Protocol.
 * Follows the 2024-11-05 basic protocol specification.
 */

#ifndef MCP_SERVER_H
#define MCP_SERVER_H

#include "mcp_message.h"
#include "mcp_resource.h"
#include "mcp_tool.h"

// Include the HTTP library
#include "httplib.h"

#include <string>
#include <map>
#include <vector>
#include <memory>
#include <mutex>
#include <thread>
#include <functional>

namespace mcp {

/**
 * @class server
 * @brief Main MCP server class
 * 
 * The server class implements an HTTP server that handles JSON-RPC requests
 * according to the Model Context Protocol specification.
 */
class server {
public:
    /**
     * @brief Constructor
     * @param host The host to bind to (e.g., "localhost", "0.0.0.0")
     * @param port The port to listen on
     */
    server(const std::string& host = "localhost", int port = 8080);
    
    /**
     * @brief Destructor
     */
    ~server();
    
    /**
     * @brief Start the server
     * @param blocking If true, this call blocks until the server stops
     * @return True if the server started successfully
     */
    bool start(bool blocking = true);
    
    /**
     * @brief Stop the server
     */
    void stop();
    
    /**
     * @brief Check if the server is running
     * @return True if the server is running
     */
    bool is_running() const;
    
    /**
     * @brief Set server information
     * @param name The name of the server
     * @param version The version of the server
     */
    void set_server_info(const std::string& name, const std::string& version);
    
    /**
     * @brief Set server capabilities
     * @param capabilities The capabilities of the server
     */
    void set_capabilities(const json& capabilities);
    
    /**
     * @brief Register a method handler
     * @param method The method name
     * @param handler The function to call when the method is invoked
     */
    void register_method(const std::string& method, std::function<json(const json&)> handler);
    
    /**
     * @brief Register a notification handler
     * @param method The notification method name
     * @param handler The function to call when the notification is received
     */
    void register_notification(const std::string& method, std::function<void(const json&)> handler);
    
    /**
     * @brief Register a resource
     * @param path The path to mount the resource at
     * @param resource The resource to register
     */
    void register_resource(const std::string& path, std::shared_ptr<resource> resource);
    
    /**
     * @brief Register a tool
     * @param tool The tool to register
     * @param handler The function to call when the tool is invoked
     */
    void register_tool(const tool& tool, tool_handler handler);
    
    /**
     * @brief Get the list of available tools
     * @return JSON array of available tools
     */
    std::vector<tool> get_tools() const;
    
    /**
     * @brief Set authentication handler
     * @param handler Function that takes a token and returns true if valid
     */
    void set_auth_handler(std::function<bool(const std::string&)> handler);

private:
    std::string host_;
    int port_;
    std::string name_;
    std::string version_;
    json capabilities_;
    
    // The HTTP server
    std::unique_ptr<httplib::Server> http_server_;
    
    // Server thread (for non-blocking mode)
    std::unique_ptr<std::thread> server_thread_;
    
    // Method handlers
    std::map<std::string, std::function<json(const json&)>> method_handlers_;
    
    // Notification handlers
    std::map<std::string, std::function<void(const json&)>> notification_handlers_;
    
    // Resources map (path -> resource)
    std::map<std::string, std::shared_ptr<resource>> resources_;
    
    // Tools map (name -> handler)
    std::map<std::string, std::pair<tool, tool_handler>> tools_;
    
    // Authentication handler
    std::function<bool(const std::string&)> auth_handler_;
    
    // Mutex for thread safety
    mutable std::mutex mutex_;
    
    // Running flag
    bool running_ = false;
    
    // Handle incoming JSON-RPC requests
    void handle_jsonrpc(const httplib::Request& req, httplib::Response& res);
    
    // Process a JSON-RPC request
    json process_request(const request& req);
    
    // Handle initialization request
    json handle_initialize(const request& req);
};


} // namespace mcp

#endif // MCP_SERVER_H