// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "topaz/lib/deprecated_loop/message_loop.h"

#include <lib/fdio/io.h>
#include <lib/zx/channel.h>
#include <lib/zx/event.h>

#include <poll.h>

#include <functional>
#include <memory>
#include <string>
#include <thread>
#include <vector>

#include "gtest/gtest.h"
#include "lib/fsl/tasks/fd_waiter.h"
#include "lib/fxl/files/unique_fd.h"
#include "lib/fxl/functional/closure.h"
#include "lib/fxl/functional/make_copyable.h"
#include "lib/fxl/macros.h"

namespace deprecated_loop {
namespace {

TEST(MessageLoop, Current) {
  EXPECT_TRUE(MessageLoop::GetCurrent() == nullptr);
  {
    MessageLoop message_loop;
    EXPECT_EQ(&message_loop, MessageLoop::GetCurrent());
  }
  EXPECT_TRUE(MessageLoop::GetCurrent() == nullptr);
}

TEST(MessageLoop, RunsTasksOnCurrentThread) {
  fxl::RefPtr<fxl::TaskRunner> task_runner;

  {
    MessageLoop loop;
    task_runner = loop.task_runner();
    EXPECT_TRUE(task_runner->RunsTasksOnCurrentThread());
    bool run_on_other_thread;
    std::thread t([task_runner, &run_on_other_thread]() {
      run_on_other_thread = task_runner->RunsTasksOnCurrentThread();
    });
    t.join();
    EXPECT_FALSE(run_on_other_thread);
  }

  EXPECT_FALSE(task_runner->RunsTasksOnCurrentThread());
}

TEST(MessageLoop, CanRunTasks) {
  bool did_run = false;
  MessageLoop loop;
  loop.task_runner()->PostTask([&did_run, &loop]() {
    EXPECT_FALSE(did_run);
    did_run = true;
  });
  loop.RunUntilIdle();
  EXPECT_TRUE(did_run);
}

TEST(MessageLoop, CanPostTasksFromTasks) {
  bool did_run = false;
  MessageLoop loop;
  fxl::Closure nested_task = [&did_run, &loop]() {
    EXPECT_FALSE(did_run);
    did_run = true;
  };
  loop.task_runner()->PostTask([&nested_task, &loop]() {
          loop.task_runner()->PostTask(std::move(nested_task));
      });
  loop.RunUntilIdle();
  EXPECT_TRUE(did_run);
}

TEST(MessageLoop, TriplyNestedTasks) {
  std::vector<std::string> tasks;
  MessageLoop loop;
  loop.task_runner()->PostTask([&tasks, &loop]() {
    tasks.push_back("one");
    loop.task_runner()->PostTask([&tasks, &loop]() {
      tasks.push_back("two");
      loop.task_runner()->PostTask(
          [&tasks, &loop]() { tasks.push_back("three"); });
    });
  });
  loop.RunUntilIdle();
  EXPECT_EQ(3u, tasks.size());
  EXPECT_EQ("one", tasks[0]);
  EXPECT_EQ("two", tasks[1]);
  EXPECT_EQ("three", tasks[2]);
}

TEST(MessageLoop, CanRunTasksInOrder) {
  std::vector<std::string> tasks;
  MessageLoop loop;
  loop.task_runner()->PostTask([&tasks]() { tasks.push_back("0"); });
  loop.task_runner()->PostTask([&tasks]() { tasks.push_back("1"); });
  loop.PostQuitTask();
  loop.task_runner()->PostTask([&tasks]() { tasks.push_back("2"); });
  loop.RunUntilIdle();
  EXPECT_EQ(2u, tasks.size());
  EXPECT_EQ("0", tasks[0]);
  EXPECT_EQ("1", tasks[1]);
}

TEST(MessageLoop, CanPreloadTasks) {
  auto incoming_queue = fxl::MakeRefCounted<internal::IncomingTaskQueue>();

  bool did_run = false;
  MessageLoop* loop_ptr = nullptr;
  incoming_queue->PostTask([&did_run, &loop_ptr]() {
    EXPECT_FALSE(did_run);
    did_run = true;
  });

  MessageLoop loop(std::move(incoming_queue));
  loop_ptr = &loop;
  loop.RunUntilIdle();
  EXPECT_TRUE(did_run);
}

TEST(MessageLoop, AfterTaskCallbacks) {
  std::vector<std::string> tasks;
  MessageLoop loop;
  loop.SetAfterTaskCallback([&tasks] { tasks.push_back("callback"); });
  loop.task_runner()->PostTask([&tasks] { tasks.push_back("0"); });
  loop.task_runner()->PostTask([&tasks] { tasks.push_back("1"); });
  loop.PostQuitTask();
  loop.task_runner()->PostTask([&tasks] { tasks.push_back("2"); });
  loop.RunUntilIdle();
  EXPECT_EQ(5u, tasks.size());
  EXPECT_EQ("0", tasks[0]);
  EXPECT_EQ("callback", tasks[1]);
  EXPECT_EQ("1", tasks[2]);
  EXPECT_EQ("callback", tasks[3]);
}

TEST(MessageLoop, RemoveAfterTaskCallbacksDuringCallback) {
  std::vector<std::string> tasks;
  MessageLoop loop;

  loop.SetAfterTaskCallback([&tasks, &loop]() {
    tasks.push_back("callback");
    loop.ClearAfterTaskCallback();
  });
  loop.task_runner()->PostTask([&tasks] { tasks.push_back("0"); });
  loop.task_runner()->PostTask([&tasks] { tasks.push_back("1"); });
  loop.RunUntilIdle();
  EXPECT_EQ(3u, tasks.size());
  EXPECT_EQ("0", tasks[0]);
  EXPECT_EQ("callback", tasks[1]);
  EXPECT_EQ("1", tasks[2]);
}

class DestructorObserver {
 public:
  DestructorObserver(fxl::Closure callback) : callback_(std::move(callback)) {}
  ~DestructorObserver() { callback_(); }

 private:
  fxl::Closure callback_;
};

TEST(MessageLoop, TaskDestructionTime) {
  bool destructed = false;
  fxl::RefPtr<fxl::TaskRunner> task_runner;

  {
    MessageLoop loop;
    task_runner = fxl::RefPtr<fxl::TaskRunner>(loop.task_runner());
    loop.RunUntilIdle();
    auto observer1 = std::make_unique<DestructorObserver>(
        [&destructed] { destructed = true; });
    task_runner->PostTask(fxl::MakeCopyable([p = std::move(observer1)]() {}));
    EXPECT_FALSE(destructed);
  }
  EXPECT_TRUE(destructed);

  destructed = false;
  auto observer2 = std::make_unique<DestructorObserver>(
      [&destructed] { destructed = true; });
  task_runner->PostTask(fxl::MakeCopyable([p = std::move(observer2)]() {}));
  EXPECT_TRUE(destructed);
}

TEST(MessageLoop, CanQuitCurrent) {
  int count = 0;
  MessageLoop loop;
  loop.task_runner()->PostTask([&count]() {
    count++;
    MessageLoop::GetCurrent()->QuitNow();
  });
  loop.task_runner()->PostTask([&count]() { count++; });
  loop.RunUntilIdle();
  EXPECT_EQ(1, count);
}

TEST(MessageLoop, CanQuitManyTimes) {
  MessageLoop loop;
  loop.QuitNow();
  loop.QuitNow();
  loop.PostQuitTask();
  loop.RunUntilIdle();
  loop.QuitNow();
  loop.QuitNow();
}

// Tests that waiting on files in a MessageLoop works.
TEST(MessageLoop, FDWaiter) {
  // Create an event and an FD that reflects that event. The fd
  // shares ownership of the event.
  zx::event fdevent;
  EXPECT_EQ(zx::event::create(0u, &fdevent), ZX_OK);
  fxl::UniqueFD fd(
      fdio_handle_fd(fdevent.get(), ZX_USER_SIGNAL_0, 0, /*shared=*/true));
  EXPECT_TRUE(fd.is_valid());

  bool callback_ran = false;
  {
    MessageLoop message_loop;
    fsl::FDWaiter waiter;

    std::thread thread([&fdevent]() {
      // Poke the fdevent, which pokes the fd.
      EXPECT_EQ(fdevent.signal(0u, ZX_USER_SIGNAL_0), ZX_OK);
    });
    auto callback = [&callback_ran, &message_loop](zx_status_t success,
                                                   uint32_t events) {
      EXPECT_EQ(success, ZX_OK);
      EXPECT_EQ(events, static_cast<uint32_t>(POLLIN));
      callback_ran = true;
      message_loop.QuitNow();
    };
    EXPECT_TRUE(waiter.Wait(callback, fd.get(), POLLIN));
    message_loop.Run();
    thread.join();
  }

  EXPECT_TRUE(callback_ran);
}

}  // namespace
}  // namespace deprecated_loop
