#ifndef WATCHDOG_WATCHDOG_H_
#define WATCHDOG_WATCHDOG_H_

#include <array>
#include <chrono>
#include <cstdint>
#include <optional>
#include <queue>
#include <string>

class WatchdogTask {
 public:
  enum class States { NOT_STARTED, RUNNING, SUSPENDED, FAULTY };

  enum class LoopResult {
    OK,
    START_REQ,
    START_WITH_WATCH_REQ,
    SUSPEND_REQ,
    CANCEL_REQ,
    TIMEOUT,
    HUNG_UP,
    FAULT
  };

  WatchdogTask();

  virtual ~WatchdogTask();

  int performOperation();

 private:
  int fd = 0;

  bool obswRunning = false;
  bool watchingObsw = false;
  bool printNotRunningLatch = false;
  std::array<uint8_t, 64> buf;
  std::queue<LoopResult> resultQueue;

  std::optional<std::chrono::time_point<std::chrono::steady_clock>> notRunningStart;
  States state = States::NOT_STARTED;

  // Primary loop. Takes care of delaying, and reading from the communication pipe and translating
  // messages to loop results.
  void watchdogLoop();
  bool stateMachine(LoopResult result);
  void pollEvent(struct pollfd& waiter);
  void parseCommands(ssize_t readLen);

  int performRunningOperation();
  int performNotRunningOperation(LoopResult type);
  int performSuspendOperation();
};

#endif /* WATCHDOG_WATCHDOG_H_ */