#include "arena_allocator.hpp"
#include "http_handler.hpp"
#include "perfetto_categories.hpp"
#include <atomic>
#include <doctest/doctest.h>

// Perfetto static storage for tests
PERFETTO_TRACK_EVENT_STATIC_STORAGE();

// Global variable needed by Connection
std::atomic<int> activeConnections{0};

// Simple test helper since Connection has complex constructor requirements
struct TestConnectionData {
  ArenaAllocator arena;
  std::string message_buffer;
  void *user_data = nullptr;

  void append_message(std::string_view data) { message_buffer += data; }

  ArenaAllocator &get_arena() { return arena; }
  const std::string &getResponse() const { return message_buffer; }
  void clearResponse() { message_buffer.clear(); }
  void reset() {
    arena.reset();
    message_buffer.clear();
  }
};

TEST_CASE("HttpHandler route parsing") {
  SUBCASE("GET routes") {
    CHECK(HttpHandler::parseRoute("GET", "/v1/version") ==
          HttpRoute::GET_version);
    CHECK(HttpHandler::parseRoute("GET", "/v1/subscribe") ==
          HttpRoute::GET_subscribe);
    CHECK(HttpHandler::parseRoute("GET", "/v1/status") ==
          HttpRoute::GET_status);
    CHECK(HttpHandler::parseRoute("GET", "/v1/retention") ==
          HttpRoute::GET_retention);
    CHECK(HttpHandler::parseRoute("GET", "/metrics") == HttpRoute::GET_metrics);
    CHECK(HttpHandler::parseRoute("GET", "/ok") == HttpRoute::GET_ok);
  }

  SUBCASE("POST routes") {
    CHECK(HttpHandler::parseRoute("POST", "/v1/commit") ==
          HttpRoute::POST_commit);
  }

  SUBCASE("PUT routes") {
    CHECK(HttpHandler::parseRoute("PUT", "/v1/retention/policy1") ==
          HttpRoute::PUT_retention);
  }

  SUBCASE("DELETE routes") {
    CHECK(HttpHandler::parseRoute("DELETE", "/v1/retention/policy1") ==
          HttpRoute::DELETE_retention);
  }

  SUBCASE("Unknown routes") {
    CHECK(HttpHandler::parseRoute("GET", "/unknown") == HttpRoute::NotFound);
    CHECK(HttpHandler::parseRoute("PATCH", "/v1/version") ==
          HttpRoute::NotFound);
  }

  SUBCASE("Query parameters stripped") {
    CHECK(HttpHandler::parseRoute("GET", "/v1/version?foo=bar") ==
          HttpRoute::GET_version);
  }
}

TEST_CASE("HttpHandler route parsing edge cases") {
  // Test just the static route parsing method since full integration testing
  // would require complex Connection setup with server dependencies

  SUBCASE("Route parsing with query parameters") {
    CHECK(HttpHandler::parseRoute("GET", "/v1/version?param=value") ==
          HttpRoute::GET_version);
    CHECK(HttpHandler::parseRoute("GET", "/v1/subscribe?stream=true") ==
          HttpRoute::GET_subscribe);
  }

  SUBCASE("Retention policy routes") {
    CHECK(HttpHandler::parseRoute("PUT", "/v1/retention/policy123") ==
          HttpRoute::PUT_retention);
    CHECK(HttpHandler::parseRoute("DELETE", "/v1/retention/policy456") ==
          HttpRoute::DELETE_retention);
    CHECK(HttpHandler::parseRoute("GET", "/v1/retention/policy789") ==
          HttpRoute::GET_retention);
  }
}

// Test helper to verify the new hook functionality
struct MockConnectionHandler : public ConnectionHandler {
  bool write_progress_called = false;
  bool write_buffer_drained_called = false;

  void on_write_progress(std::unique_ptr<Connection> &) override {
    write_progress_called = true;
  }

  void on_write_buffer_drained(std::unique_ptr<Connection> &) override {
    write_buffer_drained_called = true;
  }
};

TEST_CASE("ConnectionHandler hooks") {
  SUBCASE("on_write_buffer_drained hook exists") {
    MockConnectionHandler handler;

    // Verify hooks are available and can be overridden
    CHECK_FALSE(handler.write_progress_called);
    CHECK_FALSE(handler.write_buffer_drained_called);

    // Would normally be called by Server during write operations
    std::unique_ptr<Connection> null_conn;
    handler.on_write_progress(null_conn);
    handler.on_write_buffer_drained(null_conn);

    CHECK(handler.write_progress_called);
    CHECK(handler.write_buffer_drained_called);
  }
}
