#ifndef LINUX_DEVICES_SCEXHELPER_H_
#define LINUX_DEVICES_SCEXHELPER_H_
#include <fsfw/serialize/SerializeIF.h>
#include <mission/devices/devicedefinitions/ScexDefinitions.h>

#include <cstddef>
#include <cstdint>
#include <fstream>
#include <iostream>

class ScexHelper : public SerializeIF {
 public:
  static const ReturnValue_t INVALID_CRC = returnvalue::makeCode(0, 2);

  ScexHelper();
  ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
                          Endianness streamEndianness) const override;

  size_t getSerializedSize() const override;
  ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
                            Endianness streamEndianness = Endianness::BIG) override;
  friend std::ostream &operator<<(std::ostream &os, const ScexHelper &h);
  friend std::ofstream &operator<<(std::ofstream &os, const ScexHelper &h);

  scex::Cmds getCmd() const;
  uint8_t getCmdByteRaw() const;
  uint16_t getCrc() const;
  size_t getExpectedPacketLen() const;
  uint8_t getPacketCounter() const;
  uint16_t getPayloadLen() const;
  const uint8_t *getStart() const;
  uint8_t getTotalPacketCounter() const;

 private:
  const uint8_t *start = nullptr;
  uint16_t crc = 0;
  uint8_t cmdByteRaw = 0;
  scex::Cmds cmd = scex::Cmds::INVALID;
  int packetCounter = 0;
  int totalPacketCounter = 0;
  uint16_t payloadLen = 0;
  const uint8_t *payloadStart = 0;
  size_t totalPacketLen = 0;
};

#endif /* LINUX_DEVICES_SCEXHELPER_H_ */