#pragma once

#include <string>
#include <vector>
#include <memory>
#include "httplib.hpp"
#include "json.hpp"
#include "database.hpp"
#include "config.hpp"
#include "rate_limiter.hpp"

namespace simple_object_storage {

class PutHandler;  // Forward declaration

class Server {
public:
    Server(const ServerConfig& config);
    ~Server();

    bool start();
    void stop();
    bool validate_write_request(const httplib::Request& req, httplib::Response& res, const std::vector<std::string>& required_params, std::map<std::string, std::string>& params);
    std::pair<std::string, std::string> parse_labeltag(const std::string& labeltag) const;

    // Make these public so PutHandler can access them
    ServerConfig config_;
    std::unique_ptr<Database> db_;

    void handle_get_version(const httplib::Request& req, httplib::Response& res);

private:
    void setup_routes();
    void handle_get_object(const httplib::Request& req, httplib::Response& res);
    void handle_get_hash(const httplib::Request& req, httplib::Response& res);
    void handle_get_directory(const httplib::Request& req, httplib::Response& res);
    void handle_get_metadata(const httplib::Request& req, httplib::Response& res);
    void handle_delete_object(const httplib::Request& req, httplib::Response& res);
    void handle_exists(const httplib::Request& req, httplib::Response& res);
    void handle_cors_preflight(const httplib::Request& req, httplib::Response& res);
    void add_cors_headers(const httplib::Request& req, httplib::Response& res);
    std::string join(const std::vector<std::string>& strings, const std::string& delimiter);

    bool init_db();

    httplib::Server server_;
    bool running_;
    std::unique_ptr<PutHandler> put_handler_;
    std::unique_ptr<RateLimiter> auth_rate_limiter_;
};

} // namespace simple_object_storage 