#pragma once

#include "arena.hpp"
#include "connection.hpp"
#include <variant>

// Forward declarations
struct CommitRequest;

/**
 * Pipeline entry for commit requests that need full 4-stage processing.
 * Contains connection with parsed CommitRequest.
 */
struct CommitEntry {
  WeakRef<MessageSender> connection;
  int64_t assigned_version = 0; // Set by sequence stage
  bool resolve_success = false; // Set by resolve stage
  bool persist_success = false; // Set by persist stage

  // Copied HTTP state (pipeline threads cannot access connection user_data)
  int64_t http_request_id = 0;
  bool connection_close = false;
  const CommitRequest *commit_request = nullptr; // Points to request_arena data

  // Request arena contains parsed request data and formatted response
  Arena request_arena;

  // Response data (set by persist stage, consumed by release stage)
  // Points to response formatted in request_arena
  std::span<std::string_view> response_message;

  CommitEntry() = default; // Default constructor for variant
  explicit CommitEntry(WeakRef<MessageSender> conn, int64_t req_id,
                       bool close_conn, const CommitRequest *req, Arena arena)
      : connection(std::move(conn)), http_request_id(req_id),
        connection_close(close_conn), commit_request(req),
        request_arena(std::move(arena)) {}
};

/**
 * Pipeline entry for status requests that need sequence stage processing
 * then transfer to status threadpool.
 */
struct StatusEntry {
  WeakRef<MessageSender> connection;
  int64_t version_upper_bound = 0; // Set by sequence stage

  // Copied HTTP state
  int64_t http_request_id = 0;
  bool connection_close = false;
  std::string_view status_request_id; // Points to request_arena data

  // Request arena for HTTP request data
  Arena request_arena;

  StatusEntry() = default; // Default constructor for variant
  explicit StatusEntry(WeakRef<MessageSender> conn, int64_t req_id,
                       bool close_conn, std::string_view request_id,
                       Arena arena)
      : connection(std::move(conn)), http_request_id(req_id),
        connection_close(close_conn), status_request_id(request_id),
        request_arena(std::move(arena)) {}
};

/**
 * Pipeline entry for /ok health check requests.
 * Flows through all pipeline stages as a noop except resolve stage.
 * Resolve stage can perform configurable CPU work for benchmarking.
 */
struct HealthCheckEntry {
  WeakRef<MessageSender> connection;

  // Copied HTTP state
  int64_t http_request_id = 0;
  bool connection_close = false;

  // Request arena for formatting response
  Arena request_arena;

  // Response data (set by persist stage, consumed by release stage)
  // Points to response formatted in request_arena
  std::span<std::string_view> response_message;

  HealthCheckEntry() = default; // Default constructor for variant
  explicit HealthCheckEntry(WeakRef<MessageSender> conn, int64_t req_id,
                            bool close_conn, Arena arena)
      : connection(std::move(conn)), http_request_id(req_id),
        connection_close(close_conn), request_arena(std::move(arena)) {}
};

/**
 * Pipeline entry for coordinated shutdown of all stages.
 * Flows through all stages to ensure proper cleanup.
 */
struct ShutdownEntry {
  // Empty struct - presence indicates shutdown
};

/**
 * Pipeline entry variant type used by the commit processing pipeline.
 * Each stage pattern-matches on the variant type to handle appropriately.
 */
using PipelineEntry =
    std::variant<CommitEntry, StatusEntry, HealthCheckEntry, ShutdownEntry>;
