// 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/ddk/debug.h>
#include <lib/zx/profile.h>
#include <zircon/errors.h>

#include <ddktl/fidl.h>

#include "src/devices/misc/drivers/compat/devfs_vnode.h"
#include "src/devices/misc/drivers/compat/device.h"
#include "src/devices/misc/drivers/compat/driver.h"

extern "C" {
__EXPORT zx_status_t device_add_from_driver(zx_driver_t* drv, zx_device_t* parent,
                                            device_add_args_t* args, zx_device_t** out) {
  return parent->driver()->AddDevice(parent, args, out);
}

__EXPORT void device_init_reply(zx_device_t* dev, zx_status_t status,
                                const device_init_reply_args_t* args) {
  dev->InitReply(status);
}

__EXPORT zx_status_t device_rebind(zx_device_t* dev) { return ZX_ERR_NOT_SUPPORTED; }

__EXPORT void device_async_remove(zx_device_t* dev) { dev->Remove(); }

__EXPORT void device_unbind_reply(zx_device_t* dev) {}

__EXPORT void device_suspend_reply(zx_device_t* dev, zx_status_t status, uint8_t out_state) {}

__EXPORT void device_resume_reply(zx_device_t* dev, zx_status_t status, uint8_t out_power_state,
                                  uint32_t out_perf_state) {}

__EXPORT zx_status_t device_get_profile(zx_device_t* dev, uint32_t priority, const char* name,
                                        zx_handle_t* out_profile) {
  auto profile = dev->driver()->GetSchedulerProfile(priority, name);
  if (profile.is_ok()) {
    *out_profile = profile->release();
  }
  return profile.status_value();
}

__EXPORT zx_status_t device_get_deadline_profile(zx_device_t* device, uint64_t capacity,
                                                 uint64_t deadline, uint64_t period,
                                                 const char* name, zx_handle_t* out_profile) {
  if (device == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  auto profile = device->driver()->GetDeadlineProfile(capacity, deadline, period, name);
  if (profile.is_ok()) {
    *out_profile = profile->release();
  }
  return profile.status_value();
}

__EXPORT zx_status_t device_set_profile_by_role(zx_device_t* device, zx_handle_t thread,
                                                const char* role, size_t role_size) {
  return ZX_ERR_NOT_SUPPORTED;
}

__EXPORT zx_status_t device_get_protocol(const zx_device_t* dev, uint32_t proto_id, void* out) {
  return dev->GetProtocol(proto_id, out);
}

__EXPORT zx_status_t device_open_protocol_session_multibindable(zx_device_t* dev, uint32_t proto_id,
                                                                void* out) {
  return ZX_ERR_NOT_SUPPORTED;
}

__EXPORT zx_status_t device_close_protocol_session_multibindable(zx_device_t* dev, void* proto) {
  return ZX_ERR_NOT_SUPPORTED;
}

__EXPORT zx_off_t device_get_size(zx_device_t* dev) { return 0; }

// LibDriver Misc Interfaces

__EXPORT zx_handle_t get_root_resource() {
  std::scoped_lock lock(kDriverGlobalsLock);
  return kRootResource.get();
}

__EXPORT zx_status_t load_firmware_from_driver(zx_driver_t* drv, zx_device_t* dev, const char* path,
                                               zx_handle_t* fw, size_t* size) {
  auto result = dev->driver()->LoadFirmware(dev, path, size);
  if (result.is_error()) {
    return result.error_value();
  }
  *fw = result->release();
  return ZX_OK;
}

__EXPORT void load_firmware_async_from_driver(zx_driver_t* drv, zx_device_t* dev, const char* path,
                                              load_firmware_callback_t callback, void* ctx) {
  dev->driver()->LoadFirmwareAsync(dev, path, callback, ctx);
}

__EXPORT zx_status_t device_get_metadata(zx_device_t* dev, uint32_t type, void* buf, size_t buflen,
                                         size_t* actual) {
  return dev->GetMetadata(type, buf, buflen, actual);
}

__EXPORT zx_status_t device_get_metadata_size(zx_device_t* dev, uint32_t type, size_t* out_size) {
  return dev->GetMetadataSize(type, out_size);
}

__EXPORT zx_status_t device_add_metadata(zx_device_t* dev, uint32_t type, const void* data,
                                         size_t size) {
  return dev->AddMetadata(type, data, size);
}

__EXPORT zx_status_t device_publish_metadata(zx_device_t* dev, const char* path, uint32_t type,
                                             const void* data, size_t size) {
  return ZX_ERR_NOT_SUPPORTED;
}

__EXPORT zx_status_t device_add_composite(zx_device_t* dev, const char* name,
                                          const composite_device_desc_t* comp_desc) {
  return ZX_ERR_NOT_SUPPORTED;
}

__EXPORT bool driver_log_severity_enabled_internal(const zx_driver_t* drv,
                                                   fx_log_severity_t severity) {
  return severity >= FX_LOG_SEVERITY_DEFAULT;
}

__EXPORT void driver_logvf_internal(const zx_driver_t* drv, fx_log_severity_t severity,
                                    const char* tag, const char* file, int line, const char* msg,
                                    va_list args) {
  const_cast<zx_driver_t*>(drv)->Log(static_cast<FuchsiaLogSeverity>(severity), tag, file, line,
                                     msg, args);
}

__EXPORT void driver_logf_internal(const zx_driver_t* drv, fx_log_severity_t severity,
                                   const char* tag, const char* file, int line, const char* msg,
                                   ...) {
  va_list args;
  va_start(args, msg);
  const_cast<zx_driver_t*>(drv)->Log(static_cast<FuchsiaLogSeverity>(severity), tag, file, line,
                                     msg, args);
  va_end(args);
}

__EXPORT void device_fidl_transaction_take_ownership(fidl_txn_t* txn, device_fidl_txn_t* new_txn) {
  auto fidl_txn = FromDdkInternalTransaction(ddk::internal::Transaction::FromTxn(txn));

  ZX_ASSERT_MSG(std::holds_alternative<fidl::Transaction*>(fidl_txn),
                "Can only take ownership of transaction once\n");

  auto result = std::get<fidl::Transaction*>(fidl_txn)->TakeOwnership();
  auto new_ddk_txn = MakeDdkInternalTransaction(std::move(result));
  *new_txn = *new_ddk_txn.DeviceFidlTxn();
}

__EXPORT uint32_t device_get_fragment_count(zx_device_t* dev) {
  return static_cast<uint32_t>(dev->fragments().size());
}

__EXPORT void device_get_fragments(zx_device_t* dev, composite_device_fragment_t* comp_list,
                                   size_t comp_count, size_t* comp_actual) {
  size_t i = 0;
  for (auto& fragment : dev->fragments()) {
    size_t size = sizeof(comp_list[0].name);
    if (fragment.size() < size) {
      size = fragment.size();
    }
    strncpy(comp_list[i].name, fragment.data(), size);
    // TODO(fxbug.dev/93678): We currently don't set the device pointer.
    comp_list[i].device = nullptr;
    i++;
  }
  *comp_actual = i;
}

__EXPORT zx_status_t device_get_fragment_protocol(zx_device_t* dev, const char* name,
                                                  uint32_t proto_id, void* out) {
  bool has_fragment =
      std::find(dev->fragments().begin(), dev->fragments().end(), name) != dev->fragments().end();

  // TODO(fxbug.dev/103306): We don't actually have composite support yet, so if the
  // device isn't a composite, just pretend we found it.
  if (dev->fragments().empty()) {
    has_fragment = true;
  }

  // TODO(fxbug.dev/103734): Fix sysmem routing and remove this.
  if (!has_fragment && proto_id != ZX_PROTOCOL_SYSMEM) {
    return ZX_ERR_NOT_FOUND;
  }

  // TODO(fxbug.dev/93678): Fully support composite devices.
  FDF_LOGL(WARNING, dev->logger(),
           "DFv2 currently only supports primary fragment. Driver requests fragment %s but we are "
           "returning the primary",
           name);
  zx_status_t status = dev->GetProtocol(proto_id, out);
  if (status != ZX_OK && proto_id == ZX_PROTOCOL_SYSMEM) {
    FDF_LOGL(INFO, dev->logger(), "Returning fake sysmem fragment");
    *static_cast<sysmem_protocol_t*>(out) = *dev->driver()->sysmem().protocol();
    return ZX_OK;
  }
  return status;
}

__EXPORT zx_status_t device_get_fragment_metadata(zx_device_t* dev, const char* name, uint32_t type,
                                                  void* buf, size_t buflen, size_t* actual) {
  // TODO(fxbug.dev/93678): Fully support composite devices.
  FDF_LOGL(WARNING, dev->logger(),
           "DFv2 currently only supports primary fragment. Driver requests fragment %s but we are "
           "returning the primary",
           name);
  return dev->GetMetadata(type, buf, buflen, actual);
}

__EXPORT zx_status_t device_get_variable(zx_device_t* device, const char* name, char* out,
                                         size_t out_size, size_t* size_actual) {
  if (!strncmp(name, compat::kDfv2Variable, sizeof(compat::kDfv2Variable))) {
    if (size_actual) {
      *size_actual = 2;
    }
    if (out_size < 2) {
      return ZX_ERR_BUFFER_TOO_SMALL;
    }
    out[0] = '1';
    out[1] = 0;
    return ZX_OK;
  }
  return ZX_ERR_NOT_SUPPORTED;
}

__EXPORT zx_status_t device_connect_fidl_protocol(zx_device_t* dev, const char* protocol_name,
                                                  zx_handle_t request) {
  return dev->ConnectFragmentFidl("default", protocol_name, zx::channel(request));
}

__EXPORT zx_status_t device_connect_fragment_fidl_protocol(zx_device_t* device,
                                                           const char* fragment_name,
                                                           const char* protocol_name,
                                                           zx_handle_t request) {
  return device->ConnectFragmentFidl(fragment_name, protocol_name, zx::channel(request));
}

__EXPORT async_dispatcher_t* device_get_dispatcher(zx_device_t* dev) {
  return dev->driver()->dispatcher();
}
}
