/*
 *  Copyright 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.
 */

#if defined(WEBRTC_WIN)
// clang-format off
#include <windows.h>  // Must come first.
#include <mmsystem.h>
// clang-format on
#endif

#include <stdint.h>
#include <memory>
#include <utility>
#include <vector>

#include "absl/memory/memory.h"
#include "rtc_base/bind.h"
#include "rtc_base/event.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/task_queue_for_test.h"
#include "rtc_base/timeutils.h"
#include "test/gtest.h"

using rtc::test::TaskQueueForTest;

namespace rtc {

namespace {
// Noop on all platforms except Windows, where it turns on high precision
// multimedia timers which increases the precision of TimeMillis() while in
// scope.
class EnableHighResTimers {
 public:
#if !defined(WEBRTC_WIN)
  EnableHighResTimers() {}
#else
  EnableHighResTimers() : enabled_(timeBeginPeriod(1) == TIMERR_NOERROR) {}
  ~EnableHighResTimers() {
    if (enabled_)
      timeEndPeriod(1);
  }

 private:
  const bool enabled_;
#endif
};

void CheckCurrent(Event* signal, TaskQueue* queue) {
  EXPECT_TRUE(queue->IsCurrent());
  if (signal)
    signal->Set();
}

}  // namespace

TEST(TaskQueueTest, Construct) {
  static const char kQueueName[] = "Construct";
  TaskQueue queue(kQueueName);
  EXPECT_FALSE(queue.IsCurrent());
}

TEST(TaskQueueTest, PostAndCheckCurrent) {
  static const char kQueueName[] = "PostAndCheckCurrent";
  Event event;
  TaskQueue queue(kQueueName);

  // We're not running a task, so there shouldn't be a current queue.
  EXPECT_FALSE(queue.IsCurrent());
  EXPECT_FALSE(TaskQueue::Current());

  queue.PostTask(Bind(&CheckCurrent, &event, &queue));
  EXPECT_TRUE(event.Wait(1000));
}

TEST(TaskQueueTest, PostCustomTask) {
  static const char kQueueName[] = "PostCustomImplementation";
  TaskQueueForTest queue(kQueueName);

  class CustomTask : public QueuedTask {
   public:
    CustomTask() {}
    bool ran() const { return ran_; }

   private:
    bool Run() override {
      ran_ = true;
      return false;  // Never allow the task to be deleted by the queue.
    }

    bool ran_ = false;
  } my_task;

  queue.SendTask(&my_task);
  EXPECT_TRUE(my_task.ran());
}

TEST(TaskQueueTest, PostLambda) {
  TaskQueueForTest queue("PostLambda");
  bool ran = false;
  queue.SendTask([&ran]() { ran = true; });
  EXPECT_TRUE(ran);
}

TEST(TaskQueueTest, PostDelayedZero) {
  static const char kQueueName[] = "PostDelayedZero";
  Event event;
  TaskQueue queue(kQueueName);

  queue.PostDelayedTask([&event]() { event.Set(); }, 0);
  EXPECT_TRUE(event.Wait(1000));
}

TEST(TaskQueueTest, PostFromQueue) {
  static const char kQueueName[] = "PostFromQueue";
  Event event;
  TaskQueue queue(kQueueName);

  queue.PostTask(
      [&event, &queue]() { queue.PostTask([&event]() { event.Set(); }); });
  EXPECT_TRUE(event.Wait(1000));
}

TEST(TaskQueueTest, PostDelayed) {
  static const char kQueueName[] = "PostDelayed";
  Event event;
  TaskQueue queue(kQueueName, TaskQueue::Priority::HIGH);

  uint32_t start = Time();
  queue.PostDelayedTask(Bind(&CheckCurrent, &event, &queue), 100);
  EXPECT_TRUE(event.Wait(1000));
  uint32_t end = Time();
  // These tests are a little relaxed due to how "powerful" our test bots can
  // be.  Most recently we've seen windows bots fire the callback after 94-99ms,
  // which is why we have a little bit of leeway backwards as well.
  EXPECT_GE(end - start, 90u);
  EXPECT_NEAR(end - start, 190u, 100u);  // Accept 90-290.
}

// This task needs to be run manually due to the slowness of some of our bots.
// TODO(tommi): Can we run this on the perf bots?
TEST(TaskQueueTest, DISABLED_PostDelayedHighRes) {
  EnableHighResTimers high_res_scope;

  static const char kQueueName[] = "PostDelayedHighRes";
  Event event;
  TaskQueue queue(kQueueName, TaskQueue::Priority::HIGH);

  uint32_t start = Time();
  queue.PostDelayedTask(Bind(&CheckCurrent, &event, &queue), 3);
  EXPECT_TRUE(event.Wait(1000));
  uint32_t end = TimeMillis();
  // These tests are a little relaxed due to how "powerful" our test bots can
  // be.  Most recently we've seen windows bots fire the callback after 94-99ms,
  // which is why we have a little bit of leeway backwards as well.
  EXPECT_GE(end - start, 3u);
  EXPECT_NEAR(end - start, 3, 3u);
}

TEST(TaskQueueTest, PostMultipleDelayed) {
  static const char kQueueName[] = "PostMultipleDelayed";
  TaskQueue queue(kQueueName);

  std::vector<std::unique_ptr<Event>> events;
  for (int i = 0; i < 100; ++i) {
    events.push_back(absl::make_unique<Event>());
    queue.PostDelayedTask(Bind(&CheckCurrent, events.back().get(), &queue), i);
  }

  for (const auto& e : events)
    EXPECT_TRUE(e->Wait(1000));
}

TEST(TaskQueueTest, PostDelayedAfterDestruct) {
  static const char kQueueName[] = "PostDelayedAfterDestruct";
  Event run;
  Event deleted;
  {
    TaskQueue queue(kQueueName);
    queue.PostDelayedTask(
        rtc::NewClosure([&run] { run.Set(); }, [&deleted] { deleted.Set(); }),
        100);
  }
  // Task might outlive the TaskQueue, but still should be deleted.
  EXPECT_TRUE(deleted.Wait(200));
  EXPECT_FALSE(run.Wait(0));  // and should not run.
}

TEST(TaskQueueTest, PostAndReuse) {
  static const char kPostQueue[] = "PostQueue";
  static const char kReplyQueue[] = "ReplyQueue";
  Event event;
  TaskQueue post_queue(kPostQueue);
  TaskQueue reply_queue(kReplyQueue);

  int call_count = 0;

  class ReusedTask : public QueuedTask {
   public:
    ReusedTask(int* counter, TaskQueue* reply_queue, Event* event)
        : counter_(counter), reply_queue_(reply_queue), event_(event) {
      EXPECT_EQ(0, *counter_);
    }

   private:
    bool Run() override {
      if (++(*counter_) == 1) {
        std::unique_ptr<QueuedTask> myself(this);
        reply_queue_->PostTask(std::move(myself));
        // At this point, the object is owned by reply_queue_ and it's
        // theoratically possible that the object has been deleted (e.g. if
        // posting wasn't possible).  So, don't touch any member variables here.

        // Indicate to the current queue that ownership has been transferred.
        return false;
      } else {
        EXPECT_EQ(2, *counter_);
        EXPECT_TRUE(reply_queue_->IsCurrent());
        event_->Set();
        return true;  // Indicate that the object should be deleted.
      }
    }

    int* const counter_;
    TaskQueue* const reply_queue_;
    Event* const event_;
  };

  std::unique_ptr<ReusedTask> task(
      new ReusedTask(&call_count, &reply_queue, &event));

  post_queue.PostTask(std::move(task));
  EXPECT_TRUE(event.Wait(1000));
}

TEST(TaskQueueTest, PostCopyableClosure) {
  struct CopyableClosure {
    CopyableClosure(int* num_copies, int* num_moves, Event* event)
        : num_copies(num_copies), num_moves(num_moves), event(event) {}
    CopyableClosure(const CopyableClosure& other)
        : num_copies(other.num_copies),
          num_moves(other.num_moves),
          event(other.event) {
      ++*num_copies;
    }
    CopyableClosure(CopyableClosure&& other)
        : num_copies(other.num_copies),
          num_moves(other.num_moves),
          event(other.event) {
      ++*num_moves;
    }
    void operator()() { event->Set(); }

    int* num_copies;
    int* num_moves;
    Event* event;
  };

  int num_copies = 0;
  int num_moves = 0;
  Event event;

  static const char kPostQueue[] = "PostCopyableClosure";
  TaskQueue post_queue(kPostQueue);
  {
    CopyableClosure closure(&num_copies, &num_moves, &event);
    post_queue.PostTask(closure);
    // Destroy closure to check with msan and tsan posted task has own copy.
  }

  EXPECT_TRUE(event.Wait(1000));
  EXPECT_EQ(num_copies, 1);
  EXPECT_EQ(num_moves, 0);
}

TEST(TaskQueueTest, PostMoveOnlyClosure) {
  struct SomeState {
    explicit SomeState(Event* event) : event(event) {}
    ~SomeState() { event->Set(); }
    Event* event;
  };
  struct MoveOnlyClosure {
    MoveOnlyClosure(int* num_moves, std::unique_ptr<SomeState> state)
        : num_moves(num_moves), state(std::move(state)) {}
    MoveOnlyClosure(const MoveOnlyClosure&) = delete;
    MoveOnlyClosure(MoveOnlyClosure&& other)
        : num_moves(other.num_moves), state(std::move(other.state)) {
      ++*num_moves;
    }
    void operator()() { state.reset(); }

    int* num_moves;
    std::unique_ptr<SomeState> state;
  };

  int num_moves = 0;
  Event event;
  std::unique_ptr<SomeState> state(new SomeState(&event));

  static const char kPostQueue[] = "PostMoveOnlyClosure";
  TaskQueue post_queue(kPostQueue);
  post_queue.PostTask(MoveOnlyClosure(&num_moves, std::move(state)));

  EXPECT_TRUE(event.Wait(1000));
  EXPECT_EQ(num_moves, 1);
}

TEST(TaskQueueTest, PostMoveOnlyCleanup) {
  struct SomeState {
    explicit SomeState(Event* event) : event(event) {}
    ~SomeState() { event->Set(); }
    Event* event;
  };
  struct MoveOnlyClosure {
    void operator()() { state.reset(); }

    std::unique_ptr<SomeState> state;
  };

  Event event_run;
  Event event_cleanup;
  std::unique_ptr<SomeState> state_run(new SomeState(&event_run));
  std::unique_ptr<SomeState> state_cleanup(new SomeState(&event_cleanup));

  static const char kPostQueue[] = "PostMoveOnlyCleanup";
  TaskQueue post_queue(kPostQueue);
  post_queue.PostTask(NewClosure(MoveOnlyClosure{std::move(state_run)},
                                 MoveOnlyClosure{std::move(state_cleanup)}));

  EXPECT_TRUE(event_cleanup.Wait(1000));
  // Expect run closure to complete before cleanup closure.
  EXPECT_TRUE(event_run.Wait(0));
}

// Tests posting more messages than a queue can queue up.
// In situations like that, tasks will get dropped.
TEST(TaskQueueTest, PostALot) {
  // To destruct the event after the queue has gone out of scope.
  Event event;

  int tasks_executed = 0;
  int tasks_cleaned_up = 0;
  static const int kTaskCount = 0xffff;

  {
    static const char kQueueName[] = "PostALot";
    TaskQueue queue(kQueueName);

    // On linux, the limit of pending bytes in the pipe buffer is 0xffff.
    // So here we post a total of 0xffff+1 messages, which triggers a failure
    // case inside of the libevent queue implementation.

    queue.PostTask([&event]() { event.Wait(Event::kForever); });
    for (int i = 0; i < kTaskCount; ++i)
      queue.PostTask(NewClosure([&tasks_executed]() { ++tasks_executed; },
                                [&tasks_cleaned_up]() { ++tasks_cleaned_up; }));
    event.Set();  // Unblock the first task.
  }

  EXPECT_GE(tasks_cleaned_up, tasks_executed);
  EXPECT_EQ(kTaskCount, tasks_cleaned_up);
}

}  // namespace rtc
