/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/system_wrappers/source/event_timer_posix.h"

#include "webrtc/test/gtest.h"
#include "webrtc/base/event.h"
#include "webrtc/base/criticalsection.h"

namespace webrtc {

enum class ThreadState {
  kNotStarted,
  kWaiting,
  kRequestProcessCall,
  kCallingProcess,
  kProcessDone,
  kContinue,
  kExiting,
  kDead
};

class EventTimerPosixTest : public testing::Test, public EventTimerPosix {
 public:
  EventTimerPosixTest()
      : thread_state_(ThreadState::kNotStarted),
        process_event_(false, true),
        main_event_(false, true),
        process_thread_id_(0),
        process_thread_(nullptr) {}
  virtual ~EventTimerPosixTest() {}

  rtc::PlatformThread* CreateThread() override {
    EXPECT_TRUE(process_thread_ == nullptr);
    process_thread_ =
        new rtc::PlatformThread(Run, this, "EventTimerPosixTestThread");
    return process_thread_;
  }

  static bool Run(void* obj) {
    return static_cast<EventTimerPosixTest*>(obj)->Process();
  }

  bool Process() {
    bool res = ProcessInternal();
    if (!res) {
      rtc::CritScope cs(&lock_);
      thread_state_ = ThreadState::kDead;
      main_event_.Set();
    }
    return res;
  }

  bool ProcessInternal() {
    {
      rtc::CritScope cs(&lock_);
      if (thread_state_ == ThreadState::kNotStarted) {
        if (!ChangeThreadState(ThreadState::kNotStarted,
                               ThreadState::kContinue)) {
          ADD_FAILURE() << "Unable to start process thread";
          return false;
        }
        process_thread_id_ = rtc::CurrentThreadId();
      }
    }

    if (!ChangeThreadState(ThreadState::kContinue, ThreadState::kWaiting))
      return false;

    if (!AwaitThreadState(ThreadState::kRequestProcessCall,
                          rtc::Event::kForever))
      return false;

    if (!ChangeThreadState(ThreadState::kRequestProcessCall,
                           ThreadState::kCallingProcess))
      return false;

    EventTimerPosix::Process();

    if (!ChangeThreadState(ThreadState::kCallingProcess,
                           ThreadState::kProcessDone))
      return false;

    if (!AwaitThreadState(ThreadState::kContinue, rtc::Event::kForever))
      return false;

    return true;
  }

  bool IsProcessThread() {
    rtc::CritScope cs(&lock_);
    return process_thread_id_ == rtc::CurrentThreadId();
  }

  bool ChangeThreadState(ThreadState prev_state, ThreadState new_state) {
    rtc::CritScope cs(&lock_);
    if (thread_state_ != prev_state)
      return false;
    thread_state_ = new_state;
    if (IsProcessThread()) {
      main_event_.Set();
    } else {
      process_event_.Set();
    }
    return true;
  }

  bool AwaitThreadState(ThreadState state, int timeout) {
    rtc::Event* event = IsProcessThread() ? &process_event_ : &main_event_;
    do {
      rtc::CritScope cs(&lock_);
      if (state != ThreadState::kDead && thread_state_ == ThreadState::kExiting)
        return false;
      if (thread_state_ == state)
        return true;
    } while (event->Wait(timeout));
    return false;
  }

  bool CallProcess(int timeout_ms) {
    return AwaitThreadState(ThreadState::kWaiting, timeout_ms) &&
           ChangeThreadState(ThreadState::kWaiting,
                             ThreadState::kRequestProcessCall);
  }

  bool AwaitProcessDone(int timeout_ms) {
    return AwaitThreadState(ThreadState::kProcessDone, timeout_ms) &&
           ChangeThreadState(ThreadState::kProcessDone, ThreadState::kContinue);
  }

  void TearDown() override {
    if (process_thread_) {
      {
        rtc::CritScope cs(&lock_);
        if (thread_state_ != ThreadState::kDead) {
          thread_state_ = ThreadState::kExiting;
          process_event_.Set();
        }
      }
      ASSERT_TRUE(AwaitThreadState(ThreadState::kDead, 5000));
    }
  }

  ThreadState thread_state_;
  rtc::CriticalSection lock_;
  rtc::Event process_event_;
  rtc::Event main_event_;
  rtc::PlatformThreadId process_thread_id_;
  rtc::PlatformThread* process_thread_;
};

TEST_F(EventTimerPosixTest, WaiterBlocksUntilTimeout) {
  const int kTimerIntervalMs = 100;
  const int kTimeoutMs = 5000;
  ASSERT_TRUE(StartTimer(false, kTimerIntervalMs));
  ASSERT_TRUE(CallProcess(kTimeoutMs));
  EventTypeWrapper res = Wait(kTimeoutMs);
  EXPECT_EQ(kEventSignaled, res);
  ASSERT_TRUE(AwaitProcessDone(kTimeoutMs));
}

TEST_F(EventTimerPosixTest, WaiterWakesImmediatelyAfterTimeout) {
  const int kTimerIntervalMs = 100;
  const int kTimeoutMs = 5000;
  ASSERT_TRUE(StartTimer(false, kTimerIntervalMs));
  ASSERT_TRUE(CallProcess(kTimeoutMs));
  ASSERT_TRUE(AwaitProcessDone(kTimeoutMs));
  EventTypeWrapper res = Wait(0);
  EXPECT_EQ(kEventSignaled, res);
}

TEST_F(EventTimerPosixTest, WaiterBlocksUntilTimeoutProcessInactiveOnStart) {
  const int kTimerIntervalMs = 100;
  const int kTimeoutMs = 5000;
  // First call to StartTimer initializes thread.
  ASSERT_TRUE(StartTimer(false, kTimerIntervalMs));

  // Process thread currently _not_ blocking on Process() call.
  ASSERT_TRUE(AwaitThreadState(ThreadState::kWaiting, kTimeoutMs));

  // Start new one-off timer, then call Process().
  ASSERT_TRUE(StartTimer(false, kTimerIntervalMs));
  ASSERT_TRUE(CallProcess(kTimeoutMs));

  EventTypeWrapper res = Wait(kTimeoutMs);
  EXPECT_EQ(kEventSignaled, res);

  ASSERT_TRUE(AwaitProcessDone(kTimeoutMs));
}

}  // namespace webrtc
