#include <doctest/doctest.h>

#include "torlinkc/util/net.hpp"

using namespace torlinkc;

TEST_CASE("parseRetryAfter reads delay-seconds as milliseconds") {
  auto ms = parseRetryAfter("120");
  REQUIRE(ms.has_value());
  CHECK(*ms == 120'000);
}

TEST_CASE("parseRetryAfter returns nullopt for an empty value") { CHECK_FALSE(parseRetryAfter("").has_value()); }

TEST_CASE("parseRetryAfter parses an HTTP-date relative to now") {
  // Far enough in the future that the test can't flake on execution time.
  auto ms = parseRetryAfter("Wed, 01 Jan 2099 00:00:00 GMT");
  REQUIRE(ms.has_value());
  CHECK(*ms > 0);
}

TEST_CASE("parseRetryAfter returns nullopt for garbage") { CHECK_FALSE(parseRetryAfter("not-a-date").has_value()); }

TEST_CASE("backoffDelay never exceeds the cap") {
  for (int attempt = 0; attempt < 10; ++attempt) {
    auto ms = backoffDelay(attempt, 500, 20000);
    CHECK(ms >= 0);
    CHECK(ms <= 20000);
  }
}

TEST_CASE("backoffDelay honors an explicit Retry-After floor") {
  auto ms = backoffDelay(0, 500, 20000, 15000);
  CHECK(ms >= 15000);
}

TEST_CASE("backoffDelay grows with the attempt number (upper bound doubles each time)") {
  // The jittered value is randomized, but the *ceiling* (baseMs * 2^attempt,
  // capped) must grow monotonically until it saturates at capMs.
  CHECK(500 * (1 << 0) < 500 * (1 << 1));
  CHECK(500 * (1 << 1) < 500 * (1 << 2));
}
