#include <fsfw/timemanager/Countdown.h>

#include <catch2/catch_test_macros.hpp>
#include <chrono>
#include <thread>

#include "CatchDefinitions.h"

static constexpr bool TEST_LONGER_CD = false;
TEST_CASE("Countdown Tests", "[TestCountdown]") {
  INFO("Countdown Tests");
  Countdown count(20);
  REQUIRE(count.getTimeoutMs() == 20);
  REQUIRE(count.setTimeout(100) == static_cast<uint16_t>(returnvalue::OK));
  REQUIRE(count.getTimeoutMs() == 100);
  REQUIRE(count.setTimeout(150) == static_cast<uint16_t>(returnvalue::OK));
  REQUIRE(count.isBusy());
  REQUIRE(not count.hasTimedOut());
  uint32_t number = count.getRemainingMillis();
  REQUIRE(number > 0);
  bool blocked = false;
  while (not count.hasTimedOut()) {
    blocked = true;
  };
  REQUIRE(blocked);
  number = count.getRemainingMillis();
  REQUIRE(number == 0);
  count.resetTimer();
  REQUIRE(not count.hasTimedOut());
  REQUIRE(count.isBusy());
  count.setTimeout(100);
  REQUIRE(not count.hasTimedOut());
  std::this_thread::sleep_for(std::chrono::milliseconds(50));
  REQUIRE(not count.hasTimedOut());
  std::this_thread::sleep_for(std::chrono::milliseconds(50));
  REQUIRE(count.hasTimedOut());

  // Takes longer, disabled by default
  if (TEST_LONGER_CD) {
    count.setTimeout(2500);
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    REQUIRE(not count.hasTimedOut());
    std::this_thread::sleep_for(std::chrono::milliseconds(1500));
    REQUIRE(count.hasTimedOut());
  }
}