// Copyright 2023 The Abseil Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/synchronization/internal/kernel_timeout.h"

#include <chrono>  // NOLINT(build/c++11)
#include <limits>

#include "gtest/gtest.h"
#include "absl/base/config.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"

namespace {

#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
    defined(ABSL_HAVE_MEMORY_SANITIZER) ||  \
    defined(ABSL_HAVE_THREAD_SANITIZER) || \
    defined(__ANDROID__) || \
    defined(_WIN32) || defined(_WIN64)
constexpr absl::Duration kTimingBound = absl::Milliseconds(5);
#else
constexpr absl::Duration kTimingBound = absl::Microseconds(250);
#endif

using absl::synchronization_internal::KernelTimeout;

TEST(KernelTimeout, FiniteTimes) {
  constexpr absl::Duration kDurationsToTest[] = {
    absl::ZeroDuration(),
    absl::Nanoseconds(1),
    absl::Microseconds(1),
    absl::Milliseconds(1),
    absl::Seconds(1),
    absl::Minutes(1),
    absl::Hours(1),
    absl::Hours(1000),
    -absl::Nanoseconds(1),
    -absl::Microseconds(1),
    -absl::Milliseconds(1),
    -absl::Seconds(1),
    -absl::Minutes(1),
    -absl::Hours(1),
    -absl::Hours(1000),
  };

  for (auto duration : kDurationsToTest) {
    const absl::Time now = absl::Now();
    const absl::Time when = now + duration;
    SCOPED_TRACE(duration);
    KernelTimeout t(when);
    EXPECT_TRUE(t.has_timeout());
    EXPECT_TRUE(t.is_absolute_timeout());
    EXPECT_FALSE(t.is_relative_timeout());
    EXPECT_EQ(absl::TimeFromTimespec(t.MakeAbsTimespec()), when);
#ifndef _WIN32
    EXPECT_LE(
        absl::AbsDuration(absl::Now() + duration -
                          absl::TimeFromTimespec(
                              t.MakeClockAbsoluteTimespec(CLOCK_REALTIME))),
        absl::Milliseconds(10));
#endif
    EXPECT_LE(
        absl::AbsDuration(absl::DurationFromTimespec(t.MakeRelativeTimespec()) -
                          std::max(duration, absl::ZeroDuration())),
        kTimingBound);
    EXPECT_EQ(absl::FromUnixNanos(t.MakeAbsNanos()), when);
    EXPECT_LE(absl::AbsDuration(absl::Milliseconds(t.InMillisecondsFromNow()) -
                                std::max(duration, absl::ZeroDuration())),
              absl::Milliseconds(5));
    EXPECT_LE(absl::AbsDuration(absl::FromChrono(t.ToChronoTimePoint()) - when),
              absl::Microseconds(1));
    EXPECT_LE(absl::AbsDuration(absl::FromChrono(t.ToChronoDuration()) -
                                std::max(duration, absl::ZeroDuration())),
              kTimingBound);
  }
}

TEST(KernelTimeout, InfiniteFuture) {
  KernelTimeout t(absl::InfiniteFuture());
  EXPECT_FALSE(t.has_timeout());
  // Callers are expected to check has_timeout() instead of using the methods
  // below, but we do try to do something reasonable if they don't. We may not
  // be able to round-trip back to absl::InfiniteDuration() or
  // absl::InfiniteFuture(), but we should return a very large value.
  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
            absl::Now() + absl::Hours(100000));
#ifndef _WIN32
  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
            absl::Now() + absl::Hours(100000));
#endif
  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
            absl::Hours(100000));
  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
            absl::Now() + absl::Hours(100000));
  EXPECT_EQ(t.InMillisecondsFromNow(),
            std::numeric_limits<KernelTimeout::DWord>::max());
  EXPECT_EQ(t.ToChronoTimePoint(),
            std::chrono::time_point<std::chrono::system_clock>::max());
  EXPECT_GE(t.ToChronoDuration(), std::chrono::nanoseconds::max());
}

TEST(KernelTimeout, DefaultConstructor) {
  // The default constructor is equivalent to absl::InfiniteFuture().
  KernelTimeout t;
  EXPECT_FALSE(t.has_timeout());
  // Callers are expected to check has_timeout() instead of using the methods
  // below, but we do try to do something reasonable if they don't. We may not
  // be able to round-trip back to absl::InfiniteDuration() or
  // absl::InfiniteFuture(), but we should return a very large value.
  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
            absl::Now() + absl::Hours(100000));
#ifndef _WIN32
  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
            absl::Now() + absl::Hours(100000));
#endif
  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
            absl::Hours(100000));
  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
            absl::Now() + absl::Hours(100000));
  EXPECT_EQ(t.InMillisecondsFromNow(),
            std::numeric_limits<KernelTimeout::DWord>::max());
  EXPECT_EQ(t.ToChronoTimePoint(),
            std::chrono::time_point<std::chrono::system_clock>::max());
  EXPECT_GE(t.ToChronoDuration(), std::chrono::nanoseconds::max());
}

TEST(KernelTimeout, TimeMaxNanos) {
  // Time >= kMaxNanos should behave as no timeout.
  KernelTimeout t(absl::FromUnixNanos(std::numeric_limits<int64_t>::max()));
  EXPECT_FALSE(t.has_timeout());
  // Callers are expected to check has_timeout() instead of using the methods
  // below, but we do try to do something reasonable if they don't. We may not
  // be able to round-trip back to absl::InfiniteDuration() or
  // absl::InfiniteFuture(), but we should return a very large value.
  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
            absl::Now() + absl::Hours(100000));
#ifndef _WIN32
  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
            absl::Now() + absl::Hours(100000));
#endif
  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
            absl::Hours(100000));
  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
            absl::Now() + absl::Hours(100000));
  EXPECT_EQ(t.InMillisecondsFromNow(),
            std::numeric_limits<KernelTimeout::DWord>::max());
  EXPECT_EQ(t.ToChronoTimePoint(),
            std::chrono::time_point<std::chrono::system_clock>::max());
  EXPECT_GE(t.ToChronoDuration(), std::chrono::nanoseconds::max());
}

TEST(KernelTimeout, Never) {
  // KernelTimeout::Never() is equivalent to absl::InfiniteFuture().
  KernelTimeout t = KernelTimeout::Never();
  EXPECT_FALSE(t.has_timeout());
  // Callers are expected to check has_timeout() instead of using the methods
  // below, but we do try to do something reasonable if they don't. We may not
  // be able to round-trip back to absl::InfiniteDuration() or
  // absl::InfiniteFuture(), but we should return a very large value.
  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
            absl::Now() + absl::Hours(100000));
#ifndef _WIN32
  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
            absl::Now() + absl::Hours(100000));
#endif
  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
            absl::Hours(100000));
  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
            absl::Now() + absl::Hours(100000));
  EXPECT_EQ(t.InMillisecondsFromNow(),
            std::numeric_limits<KernelTimeout::DWord>::max());
  EXPECT_EQ(t.ToChronoTimePoint(),
            std::chrono::time_point<std::chrono::system_clock>::max());
  EXPECT_GE(t.ToChronoDuration(), std::chrono::nanoseconds::max());
}

TEST(KernelTimeout, InfinitePast) {
  KernelTimeout t(absl::InfinitePast());
  EXPECT_TRUE(t.has_timeout());
  EXPECT_TRUE(t.is_absolute_timeout());
  EXPECT_FALSE(t.is_relative_timeout());
  EXPECT_LE(absl::TimeFromTimespec(t.MakeAbsTimespec()),
            absl::FromUnixNanos(1));
#ifndef _WIN32
  EXPECT_LE(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
            absl::FromUnixSeconds(1));
#endif
  EXPECT_EQ(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
            absl::ZeroDuration());
  EXPECT_LE(absl::FromUnixNanos(t.MakeAbsNanos()), absl::FromUnixNanos(1));
  EXPECT_EQ(t.InMillisecondsFromNow(), KernelTimeout::DWord{0});
  EXPECT_LT(t.ToChronoTimePoint(), std::chrono::system_clock::from_time_t(0) +
                                       std::chrono::seconds(1));
  EXPECT_EQ(t.ToChronoDuration(), std::chrono::nanoseconds(0));
}

TEST(KernelTimeout, FiniteDurations) {
  constexpr absl::Duration kDurationsToTest[] = {
    absl::ZeroDuration(),
    absl::Nanoseconds(1),
    absl::Microseconds(1),
    absl::Milliseconds(1),
    absl::Seconds(1),
    absl::Minutes(1),
    absl::Hours(1),
    absl::Hours(1000),
  };

  for (auto duration : kDurationsToTest) {
    SCOPED_TRACE(duration);
    KernelTimeout t(duration);
    EXPECT_TRUE(t.has_timeout());
    EXPECT_FALSE(t.is_absolute_timeout());
    EXPECT_TRUE(t.is_relative_timeout());
    EXPECT_LE(absl::AbsDuration(absl::Now() + duration -
                                absl::TimeFromTimespec(t.MakeAbsTimespec())),
              absl::Milliseconds(5));
#ifndef _WIN32
    EXPECT_LE(
        absl::AbsDuration(absl::Now() + duration -
                          absl::TimeFromTimespec(
                              t.MakeClockAbsoluteTimespec(CLOCK_REALTIME))),
        absl::Milliseconds(5));
#endif
    EXPECT_LE(
        absl::AbsDuration(absl::DurationFromTimespec(t.MakeRelativeTimespec()) -
                          duration),
        kTimingBound);
    EXPECT_LE(absl::AbsDuration(absl::Now() + duration -
                                absl::FromUnixNanos(t.MakeAbsNanos())),
              absl::Milliseconds(5));
    EXPECT_LE(absl::Milliseconds(t.InMillisecondsFromNow()) - duration,
              absl::Milliseconds(5));
    EXPECT_LE(absl::AbsDuration(absl::Now() + duration -
                                absl::FromChrono(t.ToChronoTimePoint())),
              kTimingBound);
    EXPECT_LE(
        absl::AbsDuration(absl::FromChrono(t.ToChronoDuration()) - duration),
        kTimingBound);
  }
}

TEST(KernelTimeout, NegativeDurations) {
  constexpr absl::Duration kDurationsToTest[] = {
    -absl::ZeroDuration(),
    -absl::Nanoseconds(1),
    -absl::Microseconds(1),
    -absl::Milliseconds(1),
    -absl::Seconds(1),
    -absl::Minutes(1),
    -absl::Hours(1),
    -absl::Hours(1000),
    -absl::InfiniteDuration(),
  };

  for (auto duration : kDurationsToTest) {
    // Negative durations should all be converted to zero durations or "now".
    SCOPED_TRACE(duration);
    KernelTimeout t(duration);
    EXPECT_TRUE(t.has_timeout());
    EXPECT_FALSE(t.is_absolute_timeout());
    EXPECT_TRUE(t.is_relative_timeout());
    EXPECT_LE(absl::AbsDuration(absl::Now() -
                                absl::TimeFromTimespec(t.MakeAbsTimespec())),
              absl::Milliseconds(5));
#ifndef _WIN32
    EXPECT_LE(absl::AbsDuration(absl::Now() - absl::TimeFromTimespec(
                                                  t.MakeClockAbsoluteTimespec(
                                                      CLOCK_REALTIME))),
              absl::Milliseconds(5));
#endif
    EXPECT_EQ(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
              absl::ZeroDuration());
    EXPECT_LE(
        absl::AbsDuration(absl::Now() - absl::FromUnixNanos(t.MakeAbsNanos())),
        absl::Milliseconds(5));
    EXPECT_EQ(t.InMillisecondsFromNow(), KernelTimeout::DWord{0});
    EXPECT_LE(absl::AbsDuration(absl::Now() -
                                absl::FromChrono(t.ToChronoTimePoint())),
              absl::Milliseconds(5));
    EXPECT_EQ(t.ToChronoDuration(), std::chrono::nanoseconds(0));
  }
}

TEST(KernelTimeout, InfiniteDuration) {
  KernelTimeout t(absl::InfiniteDuration());
  EXPECT_FALSE(t.has_timeout());
  // Callers are expected to check has_timeout() instead of using the methods
  // below, but we do try to do something reasonable if they don't. We may not
  // be able to round-trip back to absl::InfiniteDuration() or
  // absl::InfiniteFuture(), but we should return a very large value.
  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
            absl::Now() + absl::Hours(100000));
#ifndef _WIN32
  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
            absl::Now() + absl::Hours(100000));
#endif
  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
            absl::Hours(100000));
  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
            absl::Now() + absl::Hours(100000));
  EXPECT_EQ(t.InMillisecondsFromNow(),
            std::numeric_limits<KernelTimeout::DWord>::max());
  EXPECT_EQ(t.ToChronoTimePoint(),
            std::chrono::time_point<std::chrono::system_clock>::max());
  EXPECT_GE(t.ToChronoDuration(), std::chrono::nanoseconds::max());
}

TEST(KernelTimeout, DurationMaxNanos) {
  // Duration >= kMaxNanos should behave as no timeout.
  KernelTimeout t(absl::Nanoseconds(std::numeric_limits<int64_t>::max()));
  EXPECT_FALSE(t.has_timeout());
  // Callers are expected to check has_timeout() instead of using the methods
  // below, but we do try to do something reasonable if they don't. We may not
  // be able to round-trip back to absl::InfiniteDuration() or
  // absl::InfiniteFuture(), but we should return a very large value.
  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
            absl::Now() + absl::Hours(100000));
#ifndef _WIN32
  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
            absl::Now() + absl::Hours(100000));
#endif
  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
            absl::Hours(100000));
  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
            absl::Now() + absl::Hours(100000));
  EXPECT_EQ(t.InMillisecondsFromNow(),
            std::numeric_limits<KernelTimeout::DWord>::max());
  EXPECT_EQ(t.ToChronoTimePoint(),
            std::chrono::time_point<std::chrono::system_clock>::max());
  EXPECT_GE(t.ToChronoDuration(), std::chrono::nanoseconds::max());
}

TEST(KernelTimeout, OverflowNanos) {
  // Test what happens when KernelTimeout is constructed with an absl::Duration
  // that would overflow now_nanos + duration.
  int64_t now_nanos = absl::ToUnixNanos(absl::Now());
  int64_t limit = std::numeric_limits<int64_t>::max() - now_nanos;
  absl::Duration duration = absl::Nanoseconds(limit) + absl::Seconds(1);
  KernelTimeout t(duration);
  // Timeouts should still be far in the future.
  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
            absl::Now() + absl::Hours(100000));
#ifndef _WIN32
  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
            absl::Now() + absl::Hours(100000));
#endif
  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
            absl::Hours(100000));
  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
            absl::Now() + absl::Hours(100000));
  EXPECT_LE(absl::Milliseconds(t.InMillisecondsFromNow()) - duration,
            absl::Milliseconds(5));
  EXPECT_GT(t.ToChronoTimePoint(),
            std::chrono::system_clock::now() + std::chrono::hours(100000));
  EXPECT_GT(t.ToChronoDuration(), std::chrono::hours(100000));
}

}  // namespace
