#pragma once
#include <cstdint>

enum MessageType : uint8_t { kRequest = 1, kResponse = 2, kConfirmation = 3 };

enum ClientType : uint8_t {
  kClient1_Direct = 0,   // no second request, with response
  kClient1_Control = 1,  // has second request, with response
  kClient1_Second = 2,   // it's second request, no response
  kClient2_Direct = 3,
  kClient2_Control = 4,
  kClient2_Second = 5,
};

#pragma pack(push, 1)
struct MessageHdr {
  MessageHdr(uint8_t type_) : type{type_} {}

  uint8_t type;
  uint8_t link_uuid[16];  // unique uuid
};

struct MessageRequest : MessageHdr {
  MessageRequest() : MessageHdr(kRequest) {}

  uint64_t timestamp;   // request timestamp generated by client
  uint8_t client_type;  // client type
};

struct MessageResponse : MessageHdr {
  MessageResponse() : MessageHdr(kResponse) {}

  uint64_t request_ts;  // request timestamp
  uint32_t ip_addr;
  uint16_t ip_port;
};

struct MessageConfirmation : MessageHdr {
  MessageConfirmation() : MessageHdr(kConfirmation) {}

  uint64_t request_ts;  // request timestamp
};

#pragma pack(pop)
