#ifndef LINUX_BOARDTEST_UARTTESTCLASS_H_
#define LINUX_BOARDTEST_UARTTESTCLASS_H_

#include <fsfw/container/SimpleRingBuffer.h>
#include <fsfw/globalfunctions/DleEncoder.h>
#include <fsfw/globalfunctions/DleParser.h>
#include <fsfw/timemanager/Countdown.h>
#include <fsfw_hal/linux/serial/SerialCookie.h>
#include <mission/payload/scexHelpers.h>
#include <termios.h>  // Contains POSIX terminal control definitions

#include <array>

//#include "lwgps/lwgps.h"
#include "test/TestTask.h"

class ScexUartReader;
class ScexDleParser;

class UartTestClass : public TestTask {
 public:
  UartTestClass(object_id_t objectId);

  ReturnValue_t initialize() override;
  ReturnValue_t performOneShotAction() override;
  ReturnValue_t performPeriodicAction() override;

 private:
  enum TestModes {
    GPS,
    // Solar Cell Experiment
    SCEX
  };

  enum ScexModes { SIMPLE, READER_TASK } scexMode;

  void gpsInit();
  void gpsPeriodic();

  void scexInit();
  void scexPeriodic();
  int prepareScexCmd(scex::Cmds cmd, bool tempCheck, uint8_t* cmdBuf, size_t* len);

  void scexSimplePeriodic();
  void scexSimpleInit();

  static void foundDlePacketHandler(const DleParser::Context& ctx);
  void handleFoundDlePacket(uint8_t* packet, size_t len);
  std::string random_string(std::string::size_type length);

  std::string fileId = "";
  std::string fileName = "";
  bool fileNameSet = false;
  Countdown finishCountdown = Countdown(180 * 1000);
  bool cmdSent = false;
  bool cmdDone = false;
  scex::Cmds currCmd = scex::Cmds::PING;
  TestModes mode = TestModes::GPS;
  DleEncoder dleEncoder = DleEncoder();
  SerialCookie* uartCookie = nullptr;
  size_t encodedLen = 0;
  // lwgps_t gpsData = {};
  struct termios tty = {};
  int serialPort = 0;
  bool startFound = false;
  ScexUartReader* reader = nullptr;
  std::array<uint8_t, 64> cmdBuf = {};
  std::array<uint8_t, 4096> recBuf = {};
  ScexDleParser* dleParser;
  scex::Cmds cmdHelper = scex::Cmds::INVALID;
  uint8_t recvCnt = 0;
};

#endif /* LINUX_BOARDTEST_UARTTESTCLASS_H_ */