/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * 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 "perfetto/base/build_config.h"

#include "perfetto/ext/base/unix_task_runner.h"

#include <thread>

#include "perfetto/ext/base/event_fd.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/pipe.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/utils.h"
#include "src/base/test/gtest_test_suite.h"
#include "test/gtest_and_gmock.h"

namespace perfetto {
namespace base {
namespace {

class TaskRunnerTest : public ::testing::Test {
 public:
  UnixTaskRunner task_runner;
};

TEST_F(TaskRunnerTest, PostImmediateTask) {
  auto& task_runner = this->task_runner;
  int counter = 0;
  task_runner.PostTask([&counter] { counter = (counter << 4) | 1; });
  task_runner.PostTask([&counter] { counter = (counter << 4) | 2; });
  task_runner.PostTask([&counter] { counter = (counter << 4) | 3; });
  task_runner.PostTask([&counter] { counter = (counter << 4) | 4; });
  task_runner.PostTask([&task_runner] { task_runner.Quit(); });
  task_runner.Run();
  EXPECT_EQ(0x1234, counter);
}

TEST_F(TaskRunnerTest, PostDelayedTask) {
  auto& task_runner = this->task_runner;
  int counter = 0;
  task_runner.PostDelayedTask([&counter] { counter = (counter << 4) | 1; }, 5);
  task_runner.PostDelayedTask([&counter] { counter = (counter << 4) | 2; }, 10);
  task_runner.PostDelayedTask([&counter] { counter = (counter << 4) | 3; }, 15);
  task_runner.PostDelayedTask([&counter] { counter = (counter << 4) | 4; }, 15);
  task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 20);
  task_runner.Run();
  EXPECT_EQ(0x1234, counter);
}

TEST_F(TaskRunnerTest, PostImmediateTaskFromTask) {
  auto& task_runner = this->task_runner;
  task_runner.PostTask([&task_runner] {
    task_runner.PostTask([&task_runner] { task_runner.Quit(); });
  });
  task_runner.Run();
}

TEST_F(TaskRunnerTest, PostDelayedTaskFromTask) {
  auto& task_runner = this->task_runner;
  task_runner.PostTask([&task_runner] {
    task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
  });
  task_runner.Run();
}

TEST_F(TaskRunnerTest, PostImmediateTaskFromOtherThread) {
  auto& task_runner = this->task_runner;
  ThreadChecker thread_checker;
  int counter = 0;
  std::thread thread([&task_runner, &counter, &thread_checker] {
    task_runner.PostTask([&thread_checker] {
      EXPECT_TRUE(thread_checker.CalledOnValidThread());
    });
    task_runner.PostTask([&counter] { counter = (counter << 4) | 1; });
    task_runner.PostTask([&counter] { counter = (counter << 4) | 2; });
    task_runner.PostTask([&counter] { counter = (counter << 4) | 3; });
    task_runner.PostTask([&counter] { counter = (counter << 4) | 4; });
    task_runner.PostTask([&task_runner] { task_runner.Quit(); });
  });
  task_runner.Run();
  thread.join();
  EXPECT_EQ(0x1234, counter);
}

TEST_F(TaskRunnerTest, PostDelayedTaskFromOtherThread) {
  auto& task_runner = this->task_runner;
  std::thread thread([&task_runner] {
    task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
  });
  task_runner.Run();
  thread.join();
}

TEST_F(TaskRunnerTest, AddFileDescriptorWatch) {
  auto& task_runner = this->task_runner;
  EventFd evt;
  task_runner.AddFileDescriptorWatch(evt.fd(),
                                     [&task_runner] { task_runner.Quit(); });
  evt.Notify();
  task_runner.Run();
}

TEST_F(TaskRunnerTest, RemoveFileDescriptorWatch) {
  auto& task_runner = this->task_runner;
  EventFd evt;
  evt.Notify();

  bool watch_ran = false;
  task_runner.AddFileDescriptorWatch(evt.fd(),
                                     [&watch_ran] { watch_ran = true; });
  task_runner.RemoveFileDescriptorWatch(evt.fd());
  task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
  task_runner.Run();

  EXPECT_FALSE(watch_ran);
}

TEST_F(TaskRunnerTest, RemoveFileDescriptorWatchFromTask) {
  auto& task_runner = this->task_runner;
  EventFd evt;
  evt.Notify();

  bool watch_ran = false;
  task_runner.PostTask([&task_runner, &evt] {
    task_runner.RemoveFileDescriptorWatch(evt.fd());
  });
  task_runner.AddFileDescriptorWatch(evt.fd(),
                                     [&watch_ran] { watch_ran = true; });
  task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
  task_runner.Run();

  EXPECT_FALSE(watch_ran);
}

TEST_F(TaskRunnerTest, AddFileDescriptorWatchFromAnotherWatch) {
  auto& task_runner = this->task_runner;
  EventFd evt;
  EventFd evt2;
  evt.Notify();
  evt2.Notify();
  task_runner.AddFileDescriptorWatch(evt.fd(), [&task_runner, &evt, &evt2] {
    evt.Clear();
    task_runner.AddFileDescriptorWatch(evt2.fd(),
                                       [&task_runner] { task_runner.Quit(); });
  });
  task_runner.Run();
}

TEST_F(TaskRunnerTest, RemoveFileDescriptorWatchFromAnotherWatch) {
  auto& task_runner = this->task_runner;
  EventFd evt;
  EventFd evt2;
  evt.Notify();

  bool watch_ran = false;
  task_runner.AddFileDescriptorWatch(evt.fd(), [&task_runner, &evt, &evt2] {
    evt.Clear();
    evt2.Notify();
    task_runner.RemoveFileDescriptorWatch(evt2.fd());
  });
  task_runner.AddFileDescriptorWatch(evt2.fd(),
                                     [&watch_ran] { watch_ran = true; });
  task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
  task_runner.Run();

  EXPECT_FALSE(watch_ran);
}

TEST_F(TaskRunnerTest, ReplaceFileDescriptorWatchFromAnotherWatch) {
  auto& task_runner = this->task_runner;
  EventFd evt;
  EventFd evt2;

  bool watch_ran = false;
  evt.Notify();
  task_runner.AddFileDescriptorWatch(evt.fd(), [&task_runner, &evt, &evt2] {
    evt.Clear();
    evt2.Notify();
    task_runner.RemoveFileDescriptorWatch(evt2.fd());
    task_runner.AddFileDescriptorWatch(evt2.fd(),
                                       [&task_runner] { task_runner.Quit(); });
  });
  task_runner.AddFileDescriptorWatch(evt2.fd(),
                                     [&watch_ran] { watch_ran = true; });
  task_runner.Run();

  EXPECT_FALSE(watch_ran);
}

TEST_F(TaskRunnerTest, AddFileDescriptorWatchFromAnotherThread) {
  auto& task_runner = this->task_runner;
  EventFd evt;
  evt.Notify();

  std::thread thread([&task_runner, &evt] {
    task_runner.AddFileDescriptorWatch(evt.fd(),
                                       [&task_runner] { task_runner.Quit(); });
  });
  task_runner.Run();
  thread.join();
}

TEST_F(TaskRunnerTest, FileDescriptorWatchWithMultipleEvents) {
  auto& task_runner = this->task_runner;
  EventFd evt;
  evt.Notify();

  int event_count = 0;
  task_runner.AddFileDescriptorWatch(
      evt.fd(), [&task_runner, &evt, &event_count] {
        ASSERT_LT(event_count, 3);
        if (++event_count == 3) {
          task_runner.Quit();
          return;
        }
        evt.Clear();
        task_runner.PostTask([&evt] { evt.Notify(); });
      });
  task_runner.Run();
}


TEST_F(TaskRunnerTest, PostManyDelayedTasks) {
  // Check that PostTask doesn't start failing if there are too many scheduled
  // wake-ups.
  auto& task_runner = this->task_runner;
  for (int i = 0; i < 0x1000; i++)
    task_runner.PostDelayedTask([] {}, 0);
  task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
  task_runner.Run();
}

TEST_F(TaskRunnerTest, RunAgain) {
  auto& task_runner = this->task_runner;
  int counter = 0;
  task_runner.PostTask([&task_runner, &counter] {
    counter++;
    task_runner.Quit();
  });
  task_runner.Run();
  task_runner.PostTask([&task_runner, &counter] {
    counter++;
    task_runner.Quit();
  });
  task_runner.Run();
  EXPECT_EQ(2, counter);
}

void RepeatingTask(UnixTaskRunner* task_runner) {
  task_runner->PostTask(std::bind(&RepeatingTask, task_runner));
}

TEST_F(TaskRunnerTest, FileDescriptorWatchesNotStarved) {
  auto& task_runner = this->task_runner;
  EventFd evt;
  evt.Notify();

  task_runner.PostTask(std::bind(&RepeatingTask, &task_runner));
  task_runner.AddFileDescriptorWatch(evt.fd(),
                                     [&task_runner] { task_runner.Quit(); });
  task_runner.Run();
}

void CountdownTask(UnixTaskRunner* task_runner, int* counter) {
  if (!--(*counter)) {
    task_runner->Quit();
    return;
  }
  task_runner->PostDelayedTask(std::bind(&CountdownTask, task_runner, counter),
                               1);
}

TEST_F(TaskRunnerTest, NoDuplicateFileDescriptorWatchCallbacks) {
  auto& task_runner = this->task_runner;
  EventFd evt;
  evt.Notify();

  bool watch_called = 0;
  int counter = 10;
  task_runner.AddFileDescriptorWatch(evt.fd(), [&evt, &watch_called] {
    ASSERT_FALSE(watch_called);
    evt.Clear();
    watch_called = true;
  });
  task_runner.PostTask(std::bind(&CountdownTask, &task_runner, &counter));
  task_runner.Run();
}

TEST_F(TaskRunnerTest, ReplaceFileDescriptorWatchFromOtherThread) {
  auto& task_runner = this->task_runner;
  EventFd evt;
  evt.Notify();

  // The two watch tasks here race each other. We don't particularly care which
  // wins as long as one of them runs.
  task_runner.AddFileDescriptorWatch(evt.fd(),
                                     [&task_runner] { task_runner.Quit(); });

  std::thread thread([&task_runner, &evt] {
    task_runner.RemoveFileDescriptorWatch(evt.fd());
    task_runner.AddFileDescriptorWatch(evt.fd(),
                                       [&task_runner] { task_runner.Quit(); });
  });

  task_runner.Run();
  thread.join();
}

TEST_F(TaskRunnerTest, IsIdleForTesting) {
  auto& task_runner = this->task_runner;
  task_runner.PostTask(
      [&task_runner] { EXPECT_FALSE(task_runner.IsIdleForTesting()); });
  task_runner.PostTask([&task_runner] {
    EXPECT_TRUE(task_runner.IsIdleForTesting());
    task_runner.Quit();
  });
  task_runner.Run();
}

TEST_F(TaskRunnerTest, RunsTasksOnCurrentThread) {
  auto& main_tr = this->task_runner;

  EXPECT_TRUE(main_tr.RunsTasksOnCurrentThread());
  std::thread thread([&main_tr] {
    typename std::remove_reference<decltype(main_tr)>::type second_tr;
    second_tr.PostTask([&main_tr, &second_tr] {
      EXPECT_FALSE(main_tr.RunsTasksOnCurrentThread());
      EXPECT_TRUE(second_tr.RunsTasksOnCurrentThread());
      second_tr.Quit();
    });
    second_tr.Run();
  });
  thread.join();
}

TEST_F(TaskRunnerTest, FileDescriptorWatchFairness) {
  auto& task_runner = this->task_runner;
  EventFd evt[5];
  std::map<PlatformHandle, int /*num_tasks*/> num_tasks;
  static constexpr int kNumTasksPerHandle = 100;
  for (auto& e : evt) {
    e.Notify();
    task_runner.AddFileDescriptorWatch(e.fd(), [&] {
      if (++num_tasks[e.fd()] == kNumTasksPerHandle) {
        e.Clear();
        task_runner.Quit();
      }
    });
  }

  task_runner.Run();

  // The sequence evt[0], evt[1], evt[2] should be repeated N times. On the
  // Nth time the task runner quits. All tasks should have been running at least
  // N-1 times (we can't predict which one of the tasks will quit).
  for (auto& e : evt) {
    ASSERT_GE(num_tasks[e.fd()], kNumTasksPerHandle - 1);
    ASSERT_LE(num_tasks[e.fd()], kNumTasksPerHandle);
  }
}

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

// This tests UNIX-specific behavior on pipe closure.
TEST_F(TaskRunnerTest, FileDescriptorClosedEvent) {
  auto& task_runner = this->task_runner;
  Pipe pipe = Pipe::Create();
  pipe.wr.reset();
  task_runner.AddFileDescriptorWatch(pipe.rd.get(),
                                     [&task_runner] { task_runner.Quit(); });
  task_runner.Run();
}

#endif

}  // namespace
}  // namespace base
}  // namespace perfetto
