// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// 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 "starboard/common/condition_variable.h"
#include "starboard/common/mutex.h"
#include "starboard/common/time.h"
#include "starboard/nplb/thread_helpers.h"
#include "starboard/thread.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

// The SunnyDay, SunnyDayAutoInit, and SunnyDayNearMaxTime test cases directly
// (performs checks in the test case) or indirectly (invokes DoSunnyDay() which
// performs the checks) rely on timing constraints that are prone to failure,
// such as ensuring an action happens within 10 milliseconds. This requirement
// makes the tests flaky since none of these actions can be guaranteed to always
// run within the specified time.

void DoSunnyDay(TakeThenSignalContext* context, bool check_timeout) {
  SbThread thread =
      SbThreadCreate(0, kSbThreadNoPriority, kSbThreadNoAffinity, true, NULL,
                     TakeThenSignalEntryPoint, context);

  const int64_t kDelay = 10'000;  // 10ms
  // Allow two-millisecond-level precision.
  const int64_t kPrecision = 2'000;  // 2ms

  // We know the thread hasn't signaled the condition variable yet, and won't
  // unless we tell it, so it should wait at least the whole delay time.
  if (check_timeout) {
    EXPECT_TRUE(SbMutexIsSuccess(SbMutexAcquire(&context->mutex)));
    int64_t start = CurrentMonotonicTime();
    SbConditionVariableResult result = SbConditionVariableWaitTimed(
        &context->condition, &context->mutex, kDelay);
    EXPECT_EQ(kSbConditionVariableTimedOut, result);
    int64_t elapsed = CurrentMonotonicTime() - start;
    EXPECT_LE(kDelay, elapsed + kPrecision);
    EXPECT_GT(kDelay * 2, elapsed - kPrecision);
    EXPECT_TRUE(SbMutexRelease(&context->mutex));
  }

  {
    EXPECT_TRUE(SbMutexIsSuccess(SbMutexAcquire(&context->mutex)));

    // Tell the thread to signal the condvar, which will cause it to attempt to
    // acquire the mutex we are holding.
    context->do_signal.Put();

    int64_t start = CurrentMonotonicTime();

    // We release the mutex when we wait, allowing the thread to actually do the
    // signaling, and ensuring we are waiting before it signals.
    SbConditionVariableResult result = SbConditionVariableWaitTimed(
        &context->condition, &context->mutex, kDelay);
    EXPECT_EQ(kSbConditionVariableSignaled, result);

    // We should have waited only a very small amount of time.
    EXPECT_GT(kDelay, CurrentMonotonicTime() - start);

    EXPECT_TRUE(SbMutexRelease(&context->mutex));
  }

  // Now we wait for the thread to exit.
  EXPECT_TRUE(SbThreadJoin(thread, NULL));
  EXPECT_TRUE(SbConditionVariableDestroy(&context->condition));
  EXPECT_TRUE(SbMutexDestroy(&context->mutex));
}

// Test marked as flaky because it calls DoSunnyDay().
TEST(SbConditionVariableWaitTimedTest, FLAKY_SunnyDay) {
  TakeThenSignalContext context;
  context.delay_after_signal = 0;
  EXPECT_TRUE(SbMutexCreate(&context.mutex));
  EXPECT_TRUE(SbConditionVariableCreate(&context.condition, &context.mutex));
  DoSunnyDay(&context, true);
}

// Test marked as flaky because it calls DoSunnyDay().
TEST(SbConditionVariableWaitTimedTest, FLAKY_SunnyDayAutoInit) {
  {
    TakeThenSignalContext context = {TestSemaphore(0), SB_MUTEX_INITIALIZER,
                                     SB_CONDITION_VARIABLE_INITIALIZER, 0};
    DoSunnyDay(&context, true);
  }

  // Without the initial timeout test, the two threads will be racing to
  // auto-init the mutex and condition variable. So we run several trials in
  // this mode, hoping to have the auto-initting contend in various ways.
  const int kTrials = 64;
  for (int i = 0; i < kTrials; ++i) {
    TakeThenSignalContext context = {TestSemaphore(0), SB_MUTEX_INITIALIZER,
                                     SB_CONDITION_VARIABLE_INITIALIZER, 0};
    DoSunnyDay(&context, false);
  }
}

// Test marked as flaky because it relies on timing sensitive execution similar
// to DoSunnyDay().
TEST(SbConditionVariableWaitTimedTest, FLAKY_SunnyDayNearMaxTime) {
  const int64_t kOtherDelay = 10'000;  // 10ms
  TakeThenSignalContext context = {TestSemaphore(0), SB_MUTEX_INITIALIZER,
                                   SB_CONDITION_VARIABLE_INITIALIZER,
                                   kOtherDelay};
  EXPECT_TRUE(SbMutexCreate(&context.mutex));
  EXPECT_TRUE(SbConditionVariableCreate(&context.condition, &context.mutex));
  SbThread thread =
      SbThreadCreate(0, kSbThreadNoPriority, kSbThreadNoAffinity, true, NULL,
                     TakeThenSignalEntryPoint, &context);

  // Try to wait until the end of time.
  const int64_t kDelay = kSbInt64Max;

  EXPECT_TRUE(SbMutexIsSuccess(SbMutexAcquire(&context.mutex)));

  // Tell the thread to signal the condvar, which will cause it to attempt to
  // acquire the mutex we are holding, after it waits for delay_after_signal.
  context.do_signal.Put();

  int64_t start = CurrentMonotonicTime();

  // We release the mutex when we wait, allowing the thread to actually do the
  // signaling, and ensuring we are waiting before it signals.
  SbConditionVariableResult result =
      SbConditionVariableWaitTimed(&context.condition, &context.mutex, kDelay);
  EXPECT_EQ(kSbConditionVariableSignaled, result);

  // We should have waited at least the delay_after_signal amount, but not the
  // full delay.
  // Add some padding to tolerate slightly imprecise sleeps.
  EXPECT_LT(context.delay_after_signal,
            CurrentMonotonicTime() - start + (context.delay_after_signal / 10));
  EXPECT_GT(kDelay, CurrentMonotonicTime() - start);

  EXPECT_TRUE(SbMutexRelease(&context.mutex));

  // Now we wait for the thread to exit.
  EXPECT_TRUE(SbThreadJoin(thread, NULL));
  EXPECT_TRUE(SbConditionVariableDestroy(&context.condition));
  EXPECT_TRUE(SbMutexDestroy(&context.mutex));
}

TEST(SbConditionVariableWaitTimedTest, RainyDayNull) {
  SbConditionVariableResult result =
      SbConditionVariableWaitTimed(NULL, NULL, 0);
  EXPECT_EQ(kSbConditionVariableFailed, result);

  SbMutex mutex = SB_MUTEX_INITIALIZER;
  result = SbConditionVariableWaitTimed(NULL, &mutex, 0);
  EXPECT_EQ(kSbConditionVariableFailed, result);

  SbConditionVariable condition = SB_CONDITION_VARIABLE_INITIALIZER;
  result = SbConditionVariableWaitTimed(&condition, NULL, 0);
  EXPECT_EQ(kSbConditionVariableFailed, result);
}

}  // namespace
}  // namespace nplb
}  // namespace starboard
