/*
 *  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/rtc_base/criticalsection.h"
#include "webrtc/rtc_base/event.h"
#include "webrtc/test/gtest.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
