#pragma once

#include <string_view>

#include "json_tokens.hpp"

/**
 * @brief Enumeration of all known JSON token types for WeaselDB commit
 * requests.
 *
 * This enum provides type-safe identifiers for JSON keys that can appear in
 * commit request payloads. The numeric values correspond to the token_id values
 * in the perfect hash table generated by gperf.
 *
 * The enum is designed to be complete - all valid JSON keys in commit requests
 * should have corresponding enum values. Unknown keys will map to
 * JsonTokenType::Unknown.
 */
enum class JsonTokenType {
  Unknown = 0,       ///< Unrecognized JSON key (not in perfect hash table)
  Preconditions = 1, ///< "preconditions" - array of precondition objects
  Operations = 2,    ///< "operations" - array of operation objects
  RequestId = 3,     ///< "request_id" - optional unique request identifier
  LeaderId = 4,      ///< "leader_id" - expected leader for consistency checks
  ReadVersion = 5,   ///< "read_version" - snapshot version for preconditions
  Type = 6,          ///< "type" - operation or precondition type
  Key = 7,           ///< "key" - single key for point operations
  Begin = 8,         ///< "begin" - start key for range operations
  End = 9,           ///< "end" - end key for range operations (exclusive)
  Value = 10,        ///< "value" - data value for write operations
  Version = 11,      ///< "version" - specific version for preconditions
  PointRead = 12,    ///< "point_read" - precondition type for single key reads
  RangeRead = 13,    ///< "range_read" - precondition type for range reads
  Write = 14,        ///< "write" - operation type for key-value writes
  Delete = 15,       ///< "delete" - operation type for single key deletion
  RangeDelete = 16   ///< "range_delete" - operation type for range deletion
};

/**
 * @brief Convert a JSON key string to its corresponding token type.
 *
 * This function uses the perfect hash table to efficiently determine the
 * token type for a given JSON key string. It provides O(1) lookup performance
 * compared to string comparison approaches.
 *
 * @param str JSON key string to look up
 * @return JsonTokenType corresponding to the key, or JsonTokenType::Unknown
 *         if the key is not recognized
 *
 * @example
 * ```cpp
 * JsonTokenType type = get_json_token_type("request_id");
 * if (type == JsonTokenType::RequestId) {
 *   // Handle request ID field...
 * }
 * ```
 */
inline JsonTokenType get_json_token_type(std::string_view str) {
  const JsonToken *token =
      PerfectHash::lookup_json_token(str.data(), str.size());
  if (token) {
    return static_cast<JsonTokenType>(token->token_id);
  }
  return JsonTokenType::Unknown;
}
