// Copyright 2021 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 <lib/fdf/arena.h>
#include <lib/fdf/channel.h>
#include <lib/fdf/dispatcher.h>
#include <lib/fdf/env.h>
#include <lib/fdf/internal.h>
#include <lib/fdf/testing.h>
#include <lib/fdf/token.h>
#include <lib/fit/defer.h>

#include "src/devices/bin/driver_runtime/arena.h"
#include "src/devices/bin/driver_runtime/channel.h"
#include "src/devices/bin/driver_runtime/dispatcher.h"
#include "src/devices/bin/driver_runtime/driver_context.h"
#include "src/devices/bin/driver_runtime/handle.h"
#include "src/devices/lib/log/log.h"

// fdf_arena_t interface

__EXPORT zx_status_t fdf_arena_create(uint32_t options, uint32_t tag, fdf_arena_t** out_arena) {
  return fdf_arena::Create(options, tag, out_arena);
}

__EXPORT void* fdf_arena_allocate(fdf_arena_t* arena, size_t bytes) {
  return arena->Allocate(bytes);
}

__EXPORT void fdf_arena_free(fdf_arena_t* arena, void* data) { return arena->Free(data); }

__EXPORT bool fdf_arena_contains(fdf_arena_t* arena, const void* data, size_t num_bytes) {
  return arena->Contains(data, num_bytes);
}

__EXPORT void fdf_arena_drop_ref(fdf_arena_t* arena) { arena->Destroy(); }

// fdf_channel_t interface

__EXPORT
zx_status_t fdf_channel_create(uint32_t options, fdf_handle_t* out0, fdf_handle_t* out1) {
  if (!out0 || !out1) {
    return ZX_ERR_INVALID_ARGS;
  }
  return driver_runtime::Channel::Create(options, out0, out1);
}

__EXPORT
zx_status_t fdf_channel_write(fdf_handle_t channel_handle, uint32_t options, fdf_arena_t* arena,
                              void* data, uint32_t num_bytes, zx_handle_t* handles,
                              uint32_t num_handles) {
  fbl::RefPtr<driver_runtime::Channel> channel;
  zx_status_t status =
      driver_runtime::Handle::GetObject<driver_runtime::Channel>(channel_handle, &channel);
  // TODO(https://fxbug.dev/42168124): we may want to consider killing the process.
  ZX_ASSERT_MSG(status == ZX_OK, "%s", zx_status_get_string(status));
  return channel->Write(options, arena, data, num_bytes, handles, num_handles);
}

__EXPORT
zx_status_t fdf_channel_read(fdf_handle_t channel_handle, uint32_t options, fdf_arena_t** arena,
                             void** data, uint32_t* num_bytes, zx_handle_t** handles,
                             uint32_t* num_handles) {
  fbl::RefPtr<driver_runtime::Channel> channel;
  zx_status_t status =
      driver_runtime::Handle::GetObject<driver_runtime::Channel>(channel_handle, &channel);
  // TODO(https://fxbug.dev/42168124): we may want to consider killing the process.
  ZX_ASSERT_MSG(status == ZX_OK, "%s", zx_status_get_string(status));
  return channel->Read(options, arena, data, num_bytes, handles, num_handles);
}

__EXPORT
zx_status_t fdf_channel_wait_async(struct fdf_dispatcher* dispatcher,
                                   fdf_channel_read_t* channel_read, uint32_t options) {
  if (!channel_read) {
    return ZX_ERR_INVALID_ARGS;
  }
  fbl::RefPtr<driver_runtime::Channel> channel;
  zx_status_t status =
      driver_runtime::Handle::GetObject<driver_runtime::Channel>(channel_read->channel, &channel);
  // TODO(https://fxbug.dev/42168124): we may want to consider killing the process.
  ZX_ASSERT_MSG(status == ZX_OK, "%s", zx_status_get_string(status));
  return channel->WaitAsync(dispatcher, channel_read, options);
}

__EXPORT zx_status_t fdf_channel_call(fdf_handle_t channel_handle, uint32_t options,
                                      zx_time_t deadline, const fdf_channel_call_args_t* args) {
  fbl::RefPtr<driver_runtime::Channel> channel;
  zx_status_t status =
      driver_runtime::Handle::GetObject<driver_runtime::Channel>(channel_handle, &channel);
  // TODO(https://fxbug.dev/42168124): we may want to consider killing the process.
  ZX_ASSERT_MSG(status == ZX_OK, "%s", zx_status_get_string(status));
  return channel->Call(options, deadline, args);
}

__EXPORT zx_status_t fdf_channel_cancel_wait(fdf_handle_t channel_handle) {
  fbl::RefPtr<driver_runtime::Channel> channel;
  zx_status_t status =
      driver_runtime::Handle::GetObject<driver_runtime::Channel>(channel_handle, &channel);
  // TODO(https://fxbug.dev/42168124): we may want to consider killing the process.
  ZX_ASSERT_MSG(status == ZX_OK, "%s", zx_status_get_string(status));
  return channel->CancelWait();
}

__EXPORT void fdf_handle_close(fdf_handle_t channel_handle) {
  if (channel_handle == FDF_HANDLE_INVALID) {
    return;
  }
  if (!driver_runtime::Handle::IsFdfHandle(channel_handle)) {
    zx_handle_close(channel_handle);
    return;
  }
  driver_runtime::Handle* handle = driver_runtime::Handle::MapValueToHandle(channel_handle);
  // TODO(https://fxbug.dev/42168124): we may want to consider killing the process.
  ZX_ASSERT(handle);

  fbl::RefPtr<driver_runtime::Channel> channel;
  zx_status_t status = handle->GetObject<driver_runtime::Channel>(&channel);
  if (status != ZX_OK) {
    return;
  }
  channel->Close();
  // Drop the handle.
  handle->TakeOwnership();
}

// fdf_dispatcher_t interface
__EXPORT zx_status_t fdf_dispatcher_create(uint32_t options, const char* name, size_t name_len,
                                           const char* scheduler_role, size_t scheduler_role_len,
                                           fdf_dispatcher_shutdown_observer_t* observer,
                                           fdf_dispatcher_t** out_dispatcher) {
  driver_runtime::Dispatcher* dispatcher;
  auto status = driver_runtime::Dispatcher::Create(
      options, std::string_view(name, name_len),
      std::string_view(scheduler_role, scheduler_role_len), observer, &dispatcher);
  if (status != ZX_OK) {
    return status;
  }
  *out_dispatcher = static_cast<fdf_dispatcher*>(dispatcher);
  return ZX_OK;
}

__EXPORT async_dispatcher_t* fdf_dispatcher_get_async_dispatcher(fdf_dispatcher_t* dispatcher) {
  return dispatcher->GetAsyncDispatcher();
}

__EXPORT fdf_dispatcher_t* fdf_dispatcher_downcast_async_dispatcher(
    async_dispatcher_t* dispatcher) {
  return static_cast<fdf_dispatcher*>(fdf_dispatcher::DowncastAsyncDispatcher(dispatcher));
}

__EXPORT uint32_t fdf_dispatcher_get_options(const fdf_dispatcher_t* dispatcher) {
  return dispatcher->options();
}

__EXPORT void fdf_dispatcher_shutdown_async(fdf_dispatcher_t* dispatcher) {
  return dispatcher->ShutdownAsync();
}

__EXPORT void fdf_dispatcher_destroy(fdf_dispatcher_t* dispatcher) { return dispatcher->Destroy(); }

__EXPORT fdf_dispatcher_t* fdf_dispatcher_get_current_dispatcher() {
  return static_cast<fdf_dispatcher_t*>(driver_context::GetCurrentDispatcher());
}

__EXPORT zx_status_t fdf_dispatcher_seal(fdf_dispatcher_t* dispatcher, uint32_t option) {
  return dispatcher->Seal(option);
}

__EXPORT zx_status_t fdf_token_register(zx_handle_t token, fdf_dispatcher_t* dispatcher,
                                        fdf_token_t* handler) {
  return driver_runtime::DispatcherCoordinator::TokenRegister(token, dispatcher, handler);
}

__EXPORT zx_status_t fdf_token_transfer(zx_handle_t token, fdf_handle_t handle) {
  return driver_runtime::DispatcherCoordinator::TokenTransfer(token, handle);
}

__EXPORT zx_status_t fdf_env_start() { return driver_runtime::DispatcherCoordinator::Start(); }

__EXPORT void fdf_env_reset() { return driver_runtime::DispatcherCoordinator::EnvReset(); }

__EXPORT void fdf_env_register_driver_entry(const void* driver) {
  driver_context::PushDriver(driver);
}

__EXPORT void fdf_env_register_driver_exit() { driver_context::PopDriver(); }

__EXPORT zx_status_t fdf_env_dispatcher_create_with_owner(
    const void* driver, uint32_t options, const char* name, size_t name_len,
    const char* scheduler_role, size_t scheduler_role_len,
    fdf_dispatcher_shutdown_observer_t* observer, fdf_dispatcher_t** out_dispatcher) {
  driver_context::PushDriver(driver);
  auto pop_driver = fit::defer([]() { driver_context::PopDriver(); });

  driver_runtime::Dispatcher* dispatcher;
  auto status = driver_runtime::Dispatcher::Create(
      options, std::string_view(name, name_len),
      std::string_view(scheduler_role, scheduler_role_len), observer, &dispatcher);
  if (status != ZX_OK) {
    return status;
  }
  *out_dispatcher = static_cast<fdf_dispatcher*>(dispatcher);
  return ZX_OK;
}

__EXPORT void fdf_env_dispatcher_dump(fdf_dispatcher_t* dispatcher) {
  std::vector<std::string> dump;
  dispatcher->DumpToString(&dump);
  for (auto& str : dump) {
    LOGF(INFO, "%s", str.c_str());
  }
}

__EXPORT void fdf_env_dispatcher_get_dump_deprecated(fdf_dispatcher_t* dispatcher,
                                                     char** out_dump) {
  std::vector<std::string> dump;
  dispatcher->DumpToString(&dump);

  std::string result = "";
  for (auto& str : dump) {
    result += str;
    result += "\n";
  }
  char* buf = (char*)(malloc(result.size() + 1));  // Extra char for NULL.
  memcpy(buf, result.c_str(), result.size() + 1);
  *out_dump = buf;
}

__EXPORT const void* fdf_env_get_current_driver() { return driver_context::GetCurrentDriver(); }

__EXPORT zx_status_t fdf_env_shutdown_dispatchers_async(
    const void* driver, fdf_env_driver_shutdown_observer_t* observer) {
  return driver_runtime::DispatcherCoordinator::ShutdownDispatchersAsync(driver, observer);
}

__EXPORT void fdf_env_destroy_all_dispatchers() {
  return driver_runtime::DispatcherCoordinator::DestroyAllDispatchers();
}

__EXPORT bool fdf_env_dispatcher_has_queued_tasks(fdf_dispatcher_t* dispatcher) {
  return dispatcher->HasQueuedTasks();
}

__EXPORT void fdf_internal_wait_until_all_dispatchers_idle() {
  return driver_runtime::DispatcherCoordinator::WaitUntilDispatchersIdle();
}

__EXPORT void fdf_internal_wait_until_all_dispatchers_destroyed() {
  return driver_runtime::DispatcherCoordinator::WaitUntilDispatchersDestroyed();
}

__EXPORT zx_status_t fdf_testing_create_unmanaged_dispatcher(
    const void* driver, uint32_t options, const char* name, size_t name_len,
    fdf_dispatcher_shutdown_observer_t* observer, fdf_dispatcher_t** out_dispatcher) {
  driver_context::PushDriver(driver);
  auto pop_driver = fit::defer([]() { driver_context::PopDriver(); });

  driver_runtime::Dispatcher* dispatcher;
  auto status = driver_runtime::Dispatcher::CreateUnmanagedDispatcher(
      options, std::string_view(name, name_len), observer, &dispatcher);
  if (status != ZX_OK) {
    return status;
  }
  *out_dispatcher = static_cast<fdf_dispatcher*>(dispatcher);
  return ZX_OK;
}

__EXPORT zx_status_t fdf_testing_set_default_dispatcher(fdf_dispatcher_t* dispatcher) {
  if (!driver_context::IsCallStackEmpty()) {
    return ZX_ERR_BAD_STATE;
  }

  driver_context::SetDefaultTestingDispatcher(static_cast<driver_runtime::Dispatcher*>(dispatcher));
  return ZX_OK;
}

__EXPORT zx_status_t fdf_testing_run(zx_time_t deadline, bool once) {
  return driver_runtime::DispatcherCoordinator::TestingRun(zx::time(deadline), once);
}

__EXPORT zx_status_t fdf_testing_run_until_idle() {
  return driver_runtime::DispatcherCoordinator::TestingRunUntilIdle();
}

__EXPORT void fdf_testing_quit() { driver_runtime::DispatcherCoordinator::TestingQuit(); }

__EXPORT zx_status_t fdf_testing_reset_quit() {
  return driver_runtime::DispatcherCoordinator::TestingResetQuit();
}

__EXPORT uint32_t fdf_env_get_thread_limit(const char* scheduler_role, size_t scheduler_role_len) {
  return driver_runtime::DispatcherCoordinator::GetThreadLimit(
      std::string_view(scheduler_role, scheduler_role_len));
}

__EXPORT zx_status_t fdf_env_set_thread_limit(const char* scheduler_role, size_t scheduler_role_len,
                                              uint32_t max_threads) {
  return driver_runtime::DispatcherCoordinator::SetThreadLimit(
      std::string_view(scheduler_role, scheduler_role_len), max_threads);
}
