/*
 * Copyright 2015 Facebook, Inc.
 *
 * 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
 *
 *   http://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 <folly/detail/Futex.h>
#include <folly/test/DeterministicSchedule.h>

#include <chrono>
#include <functional>
#include <ratio>
#include <thread>

#include <gflags/gflags.h>
#include <glog/logging.h>
#include <gtest/gtest.h>
#include <time.h>

using namespace folly::detail;
using namespace folly::test;
using namespace std;
using namespace std::chrono;

typedef DeterministicSchedule DSched;

template <template<typename> class Atom>
void run_basic_thread(
    Futex<Atom>& f) {
  EXPECT_TRUE(f.futexWait(0));
}

template <template<typename> class Atom>
void run_basic_tests() {
  Futex<Atom> f(0);

  EXPECT_FALSE(f.futexWait(1));
  EXPECT_EQ(f.futexWake(), 0);

  auto thr = DSched::thread(std::bind(run_basic_thread<Atom>, std::ref(f)));

  while (f.futexWake() != 1) {
    std::this_thread::yield();
  }

  DSched::join(thr);
}

template <template<typename> class Atom, typename Clock, typename Duration>
void liveClockWaitUntilTests() {
  Futex<Atom> f(0);

  /* FYI: 100 iterations in the AARCH64 qemu emulator takes about 6.5 minutes */
  for (int stress = 0; stress < 100 ; ++stress) {
    auto fp = &f; // workaround for t5336595
    auto thrA = DSched::thread([fp,stress]{
      while (true) {
        const auto deadline = time_point_cast<Duration>(
            Clock::now() + microseconds(1 << (stress % 20)));
        const auto res = fp->futexWaitUntil(0, deadline);
        EXPECT_TRUE(res == FutexResult::TIMEDOUT || res == FutexResult::AWOKEN);
        if (res == FutexResult::AWOKEN) {
          break;
        }
      }
    });

    while (f.futexWake() != 1) {
      std::this_thread::yield();
    }

    DSched::join(thrA);
  }

  {
    const auto start = Clock::now();
    const auto deadline = time_point_cast<Duration>(start + milliseconds(100));
    EXPECT_EQ(f.futexWaitUntil(0, deadline), FutexResult::TIMEDOUT);
    LOG(INFO) << "Futex wait timed out after waiting for "
              << duration_cast<milliseconds>(Clock::now() - start).count()
              << "ms using clock with " << Duration::period::den
              << " precision, should be ~100ms";
  }

  {
    const auto start = Clock::now();
    const auto deadline = time_point_cast<Duration>(
        start - 2 * start.time_since_epoch());
    EXPECT_EQ(f.futexWaitUntil(0, deadline), FutexResult::TIMEDOUT);
    LOG(INFO) << "Futex wait with invalid deadline timed out after waiting for "
              << duration_cast<milliseconds>(Clock::now() - start).count()
              << "ms using clock with " << Duration::period::den
              << " precision, should be ~0ms";
  }
}

template <typename Clock>
void deterministicAtomicWaitUntilTests() {
  Futex<DeterministicAtomic> f(0);

  // Futex wait must eventually fail with either FutexResult::TIMEDOUT or
  // FutexResult::INTERRUPTED
  const auto res = f.futexWaitUntil(0, Clock::now() + milliseconds(100));
  EXPECT_TRUE(res == FutexResult::TIMEDOUT || res == FutexResult::INTERRUPTED);
}

template<template<typename> class Atom>
void run_wait_until_tests() {
  liveClockWaitUntilTests<Atom, system_clock, system_clock::duration>();
  liveClockWaitUntilTests<Atom, steady_clock, steady_clock::duration>();

  typedef duration<int64_t, std::ratio<1, 10000000>> decimicroseconds;
  liveClockWaitUntilTests<Atom, system_clock, decimicroseconds>();
}

template <>
void run_wait_until_tests<DeterministicAtomic>() {
  deterministicAtomicWaitUntilTests<system_clock>();
  deterministicAtomicWaitUntilTests<steady_clock>();
}

uint64_t diff(uint64_t a, uint64_t b) {
  return a > b ? a - b : b - a;
}

void run_system_clock_test() {
  /* Test to verify that system_clock uses clock_gettime(CLOCK_REALTIME, ...)
   * for the time_points */
  struct timespec ts;
  const int maxIters = 1000;
  int iter = 0;
  const uint64_t delta = 10000000 /* 10 ms */;

  /** The following loop is only to make the test more robust in the presence of
   * clock adjustments that can occur. We just run the loop maxIter times and
   * expect with very high probability that there will be atleast one iteration
   * of the test during which clock adjustments > delta have not occurred. */
  while (iter < maxIters) {
    uint64_t a = duration_cast<nanoseconds>(system_clock::now()
                                            .time_since_epoch()).count();

    clock_gettime(CLOCK_REALTIME, &ts);
    uint64_t b = ts.tv_sec * 1000000000ULL + ts.tv_nsec;

    uint64_t c = duration_cast<nanoseconds>(system_clock::now()
                                            .time_since_epoch()).count();

    if (diff(a, b) <= delta &&
        diff(b, c) <= delta &&
        diff(a, c) <= 2 * delta) {
      /* Success! system_clock uses CLOCK_REALTIME for time_points */
      break;
    }
    iter++;
  }
  EXPECT_TRUE(iter < maxIters);
}

void run_steady_clock_test() {
  /* Test to verify that steady_clock uses clock_gettime(CLOCK_MONOTONIC, ...)
   * for the time_points */
  EXPECT_TRUE(steady_clock::is_steady);

  const uint64_t A = duration_cast<nanoseconds>(steady_clock::now()
                                                .time_since_epoch()).count();

  struct timespec ts;
  clock_gettime(CLOCK_MONOTONIC, &ts);
  const uint64_t B = ts.tv_sec * 1000000000ULL + ts.tv_nsec;

  const uint64_t C = duration_cast<nanoseconds>(steady_clock::now()
                                                .time_since_epoch()).count();
  EXPECT_TRUE(A <= B && B <= C);
}

TEST(Futex, clock_source) {
  run_system_clock_test();

  /* On some systems steady_clock is just an alias for system_clock. So,
   * we must skip run_steady_clock_test if the two clocks are the same. */
  if (!std::is_same<system_clock,steady_clock>::value) {
    run_steady_clock_test();
  }
}

TEST(Futex, basic_live) {
  run_basic_tests<std::atomic>();
  run_wait_until_tests<std::atomic>();
}

TEST(Futex, basic_emulated) {
  run_basic_tests<EmulatedFutexAtomic>();
  run_wait_until_tests<EmulatedFutexAtomic>();
}

TEST(Futex, basic_deterministic) {
  DSched sched(DSched::uniform(0));
  run_basic_tests<DeterministicAtomic>();
  run_wait_until_tests<DeterministicAtomic>();
}

int main(int argc, char ** argv) {
  testing::InitGoogleTest(&argc, argv);
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  return RUN_ALL_TESTS();
}
