/*
 *  Copyright 2019 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 "api/task_queue/to_queued_task.h"

#include <memory>

#include "absl/memory/memory.h"
#include "api/task_queue/queued_task.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using ::testing::InSequence;
using ::testing::MockFunction;

void RunTask(std::unique_ptr<QueuedTask> task) {
  // Simulate how task queue suppose to run tasks.
  QueuedTask* raw = task.release();
  if (raw->Run())
    delete raw;
}

TEST(ToQueuedTaskTest, AcceptsLambda) {
  bool run = false;
  std::unique_ptr<QueuedTask> task = ToQueuedTask([&run] { run = true; });
  EXPECT_FALSE(run);
  RunTask(std::move(task));
  EXPECT_TRUE(run);
}

TEST(ToQueuedTaskTest, AcceptsCopyableClosure) {
  struct CopyableClosure {
    CopyableClosure(int* num_copies, int* num_moves, int* num_runs)
        : num_copies(num_copies), num_moves(num_moves), num_runs(num_runs) {}
    CopyableClosure(const CopyableClosure& other)
        : num_copies(other.num_copies),
          num_moves(other.num_moves),
          num_runs(other.num_runs) {
      ++*num_copies;
    }
    CopyableClosure(CopyableClosure&& other)
        : num_copies(other.num_copies),
          num_moves(other.num_moves),
          num_runs(other.num_runs) {
      ++*num_moves;
    }
    void operator()() { ++*num_runs; }

    int* num_copies;
    int* num_moves;
    int* num_runs;
  };

  int num_copies = 0;
  int num_moves = 0;
  int num_runs = 0;

  std::unique_ptr<QueuedTask> task;
  {
    CopyableClosure closure(&num_copies, &num_moves, &num_runs);
    task = ToQueuedTask(closure);
    // Destroy closure to check with msan task has own copy.
  }
  EXPECT_EQ(num_copies, 1);
  EXPECT_EQ(num_runs, 0);
  RunTask(std::move(task));
  EXPECT_EQ(num_copies, 1);
  EXPECT_EQ(num_moves, 0);
  EXPECT_EQ(num_runs, 1);
}

TEST(ToQueuedTaskTest, AcceptsMoveOnlyClosure) {
  struct MoveOnlyClosure {
    MoveOnlyClosure(int* num_moves, std::function<void()> trigger)
        : num_moves(num_moves), trigger(std::move(trigger)) {}
    MoveOnlyClosure(const MoveOnlyClosure&) = delete;
    MoveOnlyClosure(MoveOnlyClosure&& other)
        : num_moves(other.num_moves), trigger(std::move(other.trigger)) {
      ++*num_moves;
    }
    void operator()() { trigger(); }

    int* num_moves;
    std::function<void()> trigger;
  };

  int num_moves = 0;
  MockFunction<void()> run;

  auto task = ToQueuedTask(MoveOnlyClosure(&num_moves, run.AsStdFunction()));
  EXPECT_EQ(num_moves, 1);
  EXPECT_CALL(run, Call);
  RunTask(std::move(task));
  EXPECT_EQ(num_moves, 1);
}

TEST(ToQueuedTaskTest, AcceptsMoveOnlyCleanup) {
  struct MoveOnlyClosure {
    MoveOnlyClosure(const MoveOnlyClosure&) = delete;
    MoveOnlyClosure(MoveOnlyClosure&&) = default;
    void operator()() { trigger(); }

    std::function<void()> trigger;
  };

  MockFunction<void()> run;
  MockFunction<void()> cleanup;

  auto task = ToQueuedTask(MoveOnlyClosure{run.AsStdFunction()},
                           MoveOnlyClosure{cleanup.AsStdFunction()});

  // Expect run closure to complete before cleanup closure.
  InSequence in_sequence;
  EXPECT_CALL(run, Call);
  EXPECT_CALL(cleanup, Call);
  RunTask(std::move(task));
}

TEST(ToQueuedTaskTest, PendingTaskSafetyFlag) {
  rtc::scoped_refptr<PendingTaskSafetyFlag> flag =
      PendingTaskSafetyFlag::Create();

  int count = 0;
  // Create two identical tasks that increment the `count`.
  auto task1 = ToQueuedTask(flag, [&count]() { ++count; });
  auto task2 = ToQueuedTask(flag, [&count]() { ++count; });

  EXPECT_EQ(0, count);
  RunTask(std::move(task1));
  EXPECT_EQ(1, count);
  flag->SetNotAlive();
  // Now task2 should actually not run.
  RunTask(std::move(task2));
  EXPECT_EQ(1, count);
}

}  // namespace
}  // namespace webrtc
