#ifndef REQUEST_HANDLER_H
#define REQUEST_HANDLER_H

#include "binom/binom.h"
#include "tcp/TcpServer.h"
#include "common.hpp"

class RequestHandler {
public:
  /**
   * @brief The ClientState enum
   */
  enum class ClientState : uint8_t {
    connected,
    secure_connected,
    authenticated
  };

private:
  binom::DynamicStorage& db;        ///< Server database
  TcpServer& server;                ///< TCP Server
  EVP_PKEY* server_key;     ///< Server key pair

  TcpServer::Client& client;            ///< TCP Client
  binom::Variable data;                 ///< recived data
  binom::FileNodeVisitor session_data;  ///< session

  std::string getHostStr();

  void routeOpenLayer();
  void routeSecuredLayer();
  void routeAuthenticatedLayer();
  void processRequest();

  void invalidActionCode();

  // Layer actions
    // Open layer
  void exchangeKey();

    // Secured layer
  void sendServerInfo();
  void authenticate();
  void registrate();
  void authenticateByUUID();

    // Authenticated layer
      // Request processing
  void changeProfile();
  void deleteAccount();
  void createDialog();
  void sendMessage();
  void changeMessage();
  void deleteMessage();
  void changePost();
  void publishPost();
  void deletePost();

  void requestUserProfiles();
  void requestUserPublicKey();
  void requestMessages();
  void requestPosts();

  // Layer gates
  void gotoSecuredLayer(); // Open -> Secu
  void gotoAuthenticatedLayer(); // Secured -> Authenticated



  /**
   * @brief Insert data in content-addressable storage
   * @param content
   * @param owner - login of data owner
   * @return hash-key of content in Content-addressable storage
   */
  binom::ByteArray insertContent(binom::ByteArray content, binom::ByteArray mime_type, binom::ByteArray owner);

  /**
   * @brief Get data from content-addressable storage
   * @param key
   * @return data entry
   */
  binom::Variable getContent(binom::ByteArray key);

  /**
   * @brief Assemble content list from content-addressable storage by hash key list
   * @param hash_key_list
   * @return
   */
  binom::Array assembleContentList(binom::Array hash_key_list);


public:
  RequestHandler(
      binom::DynamicStorage& db,
      TcpServer& server,
      EVP_PKEY* server_key,
      TcpServer::Client& client,
      binom::Variable data,
      binom::FileNodeVisitor session_data
      )
    : db(db),
      server(server),
      server_key(server_key),
      client(client),
      data(std::move(data)),
      session_data(session_data) {
    routeOpenLayer();
  }
};

#endif // REQUEST_HANDLER_H
