#ifndef LINUX_DEVICES_SYRLINKSCOMHANDLER_H_
#define LINUX_DEVICES_SYRLINKSCOMHANDLER_H_

#include <fsfw/container/SimpleRingBuffer.h>
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/tasks/SemaphoreIF.h>
#include <termios.h>

class SyrlinksComHandler : public DeviceCommunicationIF,
                           public ExecutableObjectIF,
                           public SystemObject {
 public:
  SyrlinksComHandler(object_id_t objectId);

 private:
  static constexpr char START_MARKER = '<';
  static constexpr char END_MARKER = '>';

  //! [EXPORT] : [SKIP]
  static constexpr ReturnValue_t NO_SERIAL_DATA_READ = returnvalue::makeCode(2, 0);
  //! [EXPORT] : [SKIP]
  static constexpr ReturnValue_t NO_PACKET_FOUND = returnvalue::makeCode(2, 1);

  enum class State { SLEEPING, ACTIVE } state = State::SLEEPING;

  MutexIF *lock;
  SemaphoreIF *semaphore;
  int serialPort = 0;
  struct termios tty {};
  Countdown replyTimeout = Countdown(2000);
  std::array<uint8_t, 2048> recBuf{};
  SimpleRingBuffer ringBuf;
  std::array<uint8_t, 1024> ipcBuf{};
  size_t replyLen = 0;
  ReturnValue_t replyResult = returnvalue::OK;

  ReturnValue_t handleSerialReception();

  ReturnValue_t performOperation(uint8_t opCode) override;

  ReturnValue_t initializeInterface(CookieIF *cookie) override;
  ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) override;
  ReturnValue_t getSendSuccess(CookieIF *cookie) override;
  ReturnValue_t requestReceiveMessage(CookieIF *cookie, size_t requestLen) override;
  ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) override;

  ReturnValue_t readOneReply();
  ReturnValue_t tryReadingOneSyrlinksReply();
};

#endif /* LINUX_DEVICES_SYRLINKSCOMHANDLER_H_ */