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

#define FML_USED_ON_EMBEDDER

#include "flutter/shell/platform/embedder/embedder_thread_host.h"

#include <algorithm>

#include "flutter/fml/message_loop.h"
#include "flutter/shell/platform/embedder/embedder_struct_macros.h"

namespace flutter {

//------------------------------------------------------------------------------
/// @brief      Attempts to create a task runner from an embedder task runner
///             description. The first boolean in the pair indicate whether the
///             embedder specified an invalid task runner description. In this
///             case, engine launch must be aborted. If the embedder did not
///             specify any task runner, an engine managed task runner and
///             thread must be selected instead.
///
/// @param[in]  description  The description
///
/// @return     A pair that returns if the embedder has specified a task runner
///             (null otherwise) and whether to terminate further engine launch.
///
static std::pair<bool, fml::RefPtr<EmbedderTaskRunner>>
CreateEmbedderTaskRunner(const FlutterTaskRunnerDescription* description) {
  if (description == nullptr) {
    // This is not embedder error. The embedder API will just have to create a
    // plain old task runner (and create a thread for it) instead of using a
    // task runner provided to us by the embedder.
    return {true, {}};
  }

  if (SAFE_ACCESS(description, runs_task_on_current_thread_callback, nullptr) ==
      nullptr) {
    FML_LOG(ERROR) << "FlutterTaskRunnerDescription.runs_task_on_current_"
                      "thread_callback was nullptr.";
    return {false, {}};
  }

  if (SAFE_ACCESS(description, post_task_callback, nullptr) == nullptr) {
    FML_LOG(ERROR)
        << "FlutterTaskRunnerDescription.post_task_callback was nullptr.";
    return {false, {}};
  }

  auto user_data = SAFE_ACCESS(description, user_data, nullptr);

  // ABI safety checks have been completed.
  auto post_task_callback_c = description->post_task_callback;
  auto runs_task_on_current_thread_callback_c =
      description->runs_task_on_current_thread_callback;

  EmbedderTaskRunner::DispatchTable task_runner_dispatch_table = {
      // .post_task_callback
      [post_task_callback_c, user_data](EmbedderTaskRunner* task_runner,
                                        uint64_t task_baton,
                                        fml::TimePoint target_time) -> void {
        FlutterTask task = {
            // runner
            reinterpret_cast<FlutterTaskRunner>(task_runner),
            // task
            task_baton,
        };
        post_task_callback_c(task, target_time.ToEpochDelta().ToNanoseconds(),
                             user_data);
      },
      // runs_task_on_current_thread_callback
      [runs_task_on_current_thread_callback_c, user_data]() -> bool {
        return runs_task_on_current_thread_callback_c(user_data);
      }};

  return {true, fml::MakeRefCounted<EmbedderTaskRunner>(
                    task_runner_dispatch_table,
                    SAFE_ACCESS(description, identifier, 0u))};
}

std::unique_ptr<EmbedderThreadHost>
EmbedderThreadHost::CreateEmbedderOrEngineManagedThreadHost(
    const FlutterCustomTaskRunners* custom_task_runners,
    const flutter::ThreadConfigSetter& config_setter) {
  {
    auto host =
        CreateEmbedderManagedThreadHost(custom_task_runners, config_setter);
    if (host && host->IsValid()) {
      return host;
    }
  }

  // Only attempt to create the engine managed host if the embedder did not
  // specify a custom configuration. Don't fallback to the engine managed
  // configuration if the embedder attempted to specify a configuration but
  // messed up with an incorrect configuration.
  if (custom_task_runners == nullptr) {
    auto host = CreateEngineManagedThreadHost(config_setter);
    if (host && host->IsValid()) {
      return host;
    }
  }

  return nullptr;
}

static fml::RefPtr<fml::TaskRunner> GetCurrentThreadTaskRunner() {
  fml::MessageLoop::EnsureInitializedForCurrentThread();
  return fml::MessageLoop::GetCurrent().GetTaskRunner();
}

constexpr const char* kFlutterThreadName = "io.flutter";

fml::Thread::ThreadConfig MakeThreadConfig(
    flutter::ThreadHost::Type type,
    fml::Thread::ThreadPriority priority) {
  return fml::Thread::ThreadConfig(
      flutter::ThreadHost::ThreadHostConfig::MakeThreadName(type,
                                                            kFlutterThreadName),
      priority);
}

// static
std::unique_ptr<EmbedderThreadHost>
EmbedderThreadHost::CreateEmbedderManagedThreadHost(
    const FlutterCustomTaskRunners* custom_task_runners,
    const flutter::ThreadConfigSetter& config_setter) {
  if (custom_task_runners == nullptr) {
    return nullptr;
  }

  auto thread_host_config = ThreadHost::ThreadHostConfig(config_setter);

  // The UI and IO threads are always created by the engine and the embedder has
  // no opportunity to specify task runners for the same.
  //
  // If/when more task runners are exposed, this mask will need to be updated.
  thread_host_config.SetUIConfig(MakeThreadConfig(
      ThreadHost::Type::kUi, fml::Thread::ThreadPriority::kDisplay));
  thread_host_config.SetIOConfig(MakeThreadConfig(
      ThreadHost::Type::kIo, fml::Thread::ThreadPriority::kBackground));

  auto platform_task_runner_pair = CreateEmbedderTaskRunner(
      SAFE_ACCESS(custom_task_runners, platform_task_runner, nullptr));
  auto render_task_runner_pair = CreateEmbedderTaskRunner(
      SAFE_ACCESS(custom_task_runners, render_task_runner, nullptr));

  if (!platform_task_runner_pair.first || !render_task_runner_pair.first) {
    // User error while supplying a custom task runner. Return an invalid thread
    // host. This will abort engine initialization. Don't fallback to defaults
    // if the user wanted to specify a task runner but just messed up instead.
    return nullptr;
  }

  // If the embedder has not supplied a raster task runner, one needs to be
  // created.
  if (!render_task_runner_pair.second) {
    thread_host_config.SetRasterConfig(MakeThreadConfig(
        ThreadHost::Type::kRaster, fml::Thread::ThreadPriority::kRaster));
  }

  // If both the platform task runner and the raster task runner are specified
  // and have the same identifier, store only one.
  if (platform_task_runner_pair.second && render_task_runner_pair.second) {
    if (platform_task_runner_pair.second->GetEmbedderIdentifier() ==
        render_task_runner_pair.second->GetEmbedderIdentifier()) {
      render_task_runner_pair.second = platform_task_runner_pair.second;
    }
  }

  // Create a thread host with just the threads that need to be managed by the
  // engine. The embedder has provided the rest.
  ThreadHost thread_host(thread_host_config);

  // If the embedder has supplied a platform task runner, use that. If not, use
  // the current thread task runner.
  auto platform_task_runner = platform_task_runner_pair.second
                                  ? static_cast<fml::RefPtr<fml::TaskRunner>>(
                                        platform_task_runner_pair.second)
                                  : GetCurrentThreadTaskRunner();

  // If the embedder has supplied a raster task runner, use that. If not, use
  // the one from our thread host.
  auto render_task_runner = render_task_runner_pair.second
                                ? static_cast<fml::RefPtr<fml::TaskRunner>>(
                                      render_task_runner_pair.second)
                                : thread_host.raster_thread->GetTaskRunner();

  flutter::TaskRunners task_runners(
      kFlutterThreadName,
      platform_task_runner,                    // platform
      render_task_runner,                      // raster
      thread_host.ui_thread->GetTaskRunner(),  // ui (always engine managed)
      thread_host.io_thread->GetTaskRunner()   // io (always engine managed)
  );

  if (!task_runners.IsValid()) {
    return nullptr;
  }

  std::set<fml::RefPtr<EmbedderTaskRunner>> embedder_task_runners;

  if (platform_task_runner_pair.second) {
    embedder_task_runners.insert(platform_task_runner_pair.second);
  }

  if (render_task_runner_pair.second) {
    embedder_task_runners.insert(render_task_runner_pair.second);
  }

  auto embedder_host = std::make_unique<EmbedderThreadHost>(
      std::move(thread_host), std::move(task_runners),
      std::move(embedder_task_runners));

  if (embedder_host->IsValid()) {
    return embedder_host;
  }

  return nullptr;
}

// static
std::unique_ptr<EmbedderThreadHost>
EmbedderThreadHost::CreateEngineManagedThreadHost(
    const flutter::ThreadConfigSetter& config_setter) {
  // Crate a thraed host config, and specified the thread name and priority.
  auto thread_host_config = ThreadHost::ThreadHostConfig(config_setter);
  thread_host_config.SetUIConfig(MakeThreadConfig(
      flutter::ThreadHost::kUi, fml::Thread::ThreadPriority::kDisplay));
  thread_host_config.SetRasterConfig(MakeThreadConfig(
      flutter::ThreadHost::kRaster, fml::Thread::ThreadPriority::kRaster));
  thread_host_config.SetIOConfig(MakeThreadConfig(
      flutter::ThreadHost::kIo, fml::Thread::ThreadPriority::kBackground));

  // Create a thread host with the current thread as the platform thread and all
  // other threads managed.
  ThreadHost thread_host(thread_host_config);

  // For embedder platforms that don't have native message loop interop, this
  // will reference a task runner that points to a null message loop
  // implementation.
  auto platform_task_runner = GetCurrentThreadTaskRunner();

  flutter::TaskRunners task_runners(
      kFlutterThreadName,
      platform_task_runner,                        // platform
      thread_host.raster_thread->GetTaskRunner(),  // raster
      thread_host.ui_thread->GetTaskRunner(),      // ui
      thread_host.io_thread->GetTaskRunner()       // io
  );

  if (!task_runners.IsValid()) {
    return nullptr;
  }

  std::set<fml::RefPtr<EmbedderTaskRunner>> empty_embedder_task_runners;

  auto embedder_host = std::make_unique<EmbedderThreadHost>(
      std::move(thread_host), std::move(task_runners),
      empty_embedder_task_runners);

  if (embedder_host->IsValid()) {
    return embedder_host;
  }

  return nullptr;
}

EmbedderThreadHost::EmbedderThreadHost(
    ThreadHost host,
    const flutter::TaskRunners& runners,
    const std::set<fml::RefPtr<EmbedderTaskRunner>>& embedder_task_runners)
    : host_(std::move(host)), runners_(runners) {
  for (const auto& runner : embedder_task_runners) {
    runners_map_[reinterpret_cast<int64_t>(runner.get())] = runner;
  }
}

EmbedderThreadHost::~EmbedderThreadHost() = default;

bool EmbedderThreadHost::IsValid() const {
  return runners_.IsValid();
}

const flutter::TaskRunners& EmbedderThreadHost::GetTaskRunners() const {
  return runners_;
}

bool EmbedderThreadHost::PostTask(int64_t runner, uint64_t task) const {
  auto found = runners_map_.find(runner);
  if (found == runners_map_.end()) {
    return false;
  }
  return found->second->PostTask(task);
}

}  // namespace flutter
