// 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/syslog/global.h>
#include <lib/syslog/logger.h>
#include <stdarg.h>
#include <stdlib.h>
#include <zircon/assert.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <mutex>
#include <utility>

#include "src/devices/testing/mock-ddk/mock-device.h"

namespace {

// Drivers can call into the ddk from separate threads.
// This mutex ensures all calls into the mock-ddk are synchronized.
std::mutex libdriver_lock;

// We will use a separate mutex for the logging related functions.
// This is because the other libdriver functions may log while they already
// have the libdriver_lock.
std::mutex libdriver_logger_lock;

}  // namespace

namespace mock_ddk {

__EXPORT void SetMinLogSeverity(fx_log_severity_t severity) {
  std::lock_guard guard(libdriver_logger_lock);
  fx_logger_t* logger = fx_log_get_logger();
  fx_logger_set_min_severity(logger, severity);
}

}  // namespace mock_ddk

// Checks to possibly keep:
// InitReply:
//   If the init fails, the device should be automatically unbound and removed.
// AsyncRemove
//   We should not call unbind until the init hook has been replied to.

__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) {
  std::lock_guard guard(libdriver_lock);
  return MockDevice::Create(args, parent, out);
}

// These calls are not supported by root parent devices:
__EXPORT
void device_async_remove(zx_device_t* device) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    zxlogf(ERROR, "Error: %s passed a null device\n", __func__);
    return;
  }
  if (device->IsRootParent()) {
    zxlogf(ERROR, "Error: Mock parent device does not support %s\n", __func__);
    return;
  }
  device->RecordAsyncRemove(ZX_OK);
}

__EXPORT
void device_init_reply(zx_device_t* device, zx_status_t status,
                       const device_init_reply_args_t* args) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    zxlogf(ERROR, "Error: %s passed a null device\n", __func__);
    return;
  }
  if (device->IsRootParent()) {
    zxlogf(ERROR, "Error: Mock parent device does not support %s\n", __func__);
    return;
  }
  device->RecordInitReply(status);
}

__EXPORT
void device_unbind_reply(zx_device_t* device) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    zxlogf(ERROR, "Error: %s passed a null device\n", __func__);
    return;
  }
  if (device->IsRootParent()) {
    zxlogf(ERROR, "Error: Mock parent device does not support %s\n", __func__);
    return;
  }
  device->RecordUnbindReply(ZX_OK);
}

__EXPORT void device_suspend_reply(zx_device_t* device, zx_status_t status, uint8_t out_state) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    zxlogf(ERROR, "Error: %s passed a null device\n", __func__);
    return;
  }
  if (device->IsRootParent()) {
    zxlogf(ERROR, "Error: Mock parent device does not support %s\n", __func__);
    return;
  }
  device->RecordSuspendReply(status);
}

__EXPORT void device_resume_reply(zx_device_t* device, zx_status_t status, uint8_t out_power_state,
                                  uint32_t out_perf_state) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    zxlogf(ERROR, "Error: %s passed a null device\n", __func__);
    return;
  }
  if (device->IsRootParent()) {
    zxlogf(ERROR, "Error: Mock parent device does not support %s\n", __func__);
    return;
  }
  device->RecordResumeReply(status);
}

// These functions TODO(will be) supported by devices created as root parents:
__EXPORT
zx_status_t device_get_protocol(const zx_device_t* device, uint32_t proto_id, void* protocol) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  return device->GetProtocol(proto_id, protocol);
}

__EXPORT zx_status_t device_get_config_vmo(zx_device_t* device, zx_handle_t* config_vmo) {
  std::lock_guard guard(libdriver_lock);
  if (device == nullptr || config_vmo == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  *config_vmo = device->GetConfigVmo().release();
  return ZX_OK;
}

__EXPORT
zx_status_t device_add_metadata(zx_device_t* device, uint32_t type, const void* data,
                                size_t length) {
  std::lock_guard guard(libdriver_lock);
  device->SetMetadata(type, data, length);
  return ZX_OK;
}

__EXPORT
zx_status_t device_get_metadata(zx_device_t* device, uint32_t type, void* buf, size_t buflen,
                                size_t* actual) {
  std::lock_guard guard(libdriver_lock);
  return device->GetMetadata(type, buf, buflen, actual);
}

__EXPORT
zx_status_t device_get_metadata_size(zx_device_t* device, uint32_t type, size_t* out_size) {
  std::lock_guard guard(libdriver_lock);
  return device->GetMetadataSize(type, out_size);
}

__EXPORT zx_status_t device_get_fragment_protocol(zx_device_t* device, const char* name,
                                                  uint32_t proto_id, void* protocol) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  return device->GetProtocol(proto_id, protocol, name);
}

__EXPORT
zx_status_t device_get_fragment_metadata(zx_device_t* device, const char* name, uint32_t type,
                                         void* buf, size_t buflen, size_t* actual) {
  // The libdriver_lock will be locked in `device_get_metadata`.
  return device_get_metadata(device, type, buf, buflen, actual);
}

__EXPORT zx_status_t device_connect_fidl_protocol2(zx_device_t* device, const char* service_name,
                                                   const char* protocol_name, zx_handle_t request) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  return device->ConnectToFidlProtocol(service_name, protocol_name, zx::channel(request));
}

__EXPORT zx_status_t device_connect_fragment_fidl_protocol(zx_device_t* device,
                                                           const char* fragment_name,
                                                           const char* service_name,
                                                           const char* protocol_name,
                                                           zx_handle_t request) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  return device->ConnectToFidlProtocol(service_name, protocol_name, zx::channel(request),
                                       fragment_name);
}

__EXPORT zx_status_t device_connect_runtime_protocol(zx_device_t* device, const char* service_name,
                                                     const char* protocol_name,
                                                     fdf_handle_t request) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  return device->ConnectToRuntimeProtocol(service_name, protocol_name, fdf::Channel(request));
}

__EXPORT zx_status_t device_connect_fragment_runtime_protocol(zx_device_t* device,
                                                              const char* fragment_name,
                                                              const char* service_name,
                                                              const char* protocol_name,
                                                              fdf_handle_t request) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  return device->ConnectToRuntimeProtocol(service_name, protocol_name, fdf::Channel(request),
                                          fragment_name);
}

__EXPORT zx_status_t device_connect_ns_protocol(zx_device_t* device, const char* protocol_name,
                                                zx_handle_t request) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  return device->ConnectToNsProtocol(protocol_name, zx::channel(request));
}

// Unsupported calls:
__EXPORT
zx_status_t device_set_profile_by_role(zx_device_t* device, zx_handle_t thread, const char* role,
                                       size_t role_size) {
  // This is currently a no-op.
  return ZX_OK;
}

__EXPORT __WEAK zx_status_t load_firmware_from_driver(zx_driver_t* drv, zx_device_t* device,
                                                      const char* path, zx_handle_t* fw,
                                                      size_t* size) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    zxlogf(ERROR, "Error: %s passed a null device\n", __func__);
    return ZX_ERR_INVALID_ARGS;
  }
  return device->LoadFirmware(path, fw, size);
}

__EXPORT zx_status_t device_get_variable(zx_device_t* device, const char* name, char* out,
                                         size_t out_size, size_t* size_actual) {
  std::lock_guard guard(libdriver_lock);
  if (!device) {
    zxlogf(ERROR, "Error: %s passed a null device\n", __func__);
    return ZX_ERR_INVALID_ARGS;
  }

  return device->GetVariable(name, out, out_size, size_actual);
}

__EXPORT
zx_handle_t get_mmio_resource(zx_device_t* parent) { return ZX_HANDLE_INVALID; }

__EXPORT
zx_handle_t get_ioport_resource(zx_device_t* parent) { return ZX_HANDLE_INVALID; }

__EXPORT
zx_handle_t get_iommu_resource(zx_device_t* parent) { return ZX_HANDLE_INVALID; }

__EXPORT
zx_handle_t get_framebuffer_resource(zx_device_t* parent) { return ZX_HANDLE_INVALID; }

__EXPORT
zx_handle_t get_irq_resource(zx_device_t* parent) { return ZX_HANDLE_INVALID; }

__EXPORT
zx_handle_t get_info_resource(zx_device_t* parent) { return ZX_HANDLE_INVALID; }

__EXPORT
zx_handle_t get_smc_resource(zx_device_t* parent) { return ZX_HANDLE_INVALID; }

__EXPORT
zx_handle_t get_power_resource(zx_device_t* parent) { return ZX_HANDLE_INVALID; }

__EXPORT
zx_handle_t get_msi_resource(zx_device_t* parent) { return ZX_HANDLE_INVALID; }

extern "C" bool driver_log_severity_enabled_internal(const zx_driver_t* drv,
                                                     fx_log_severity_t flag) {
  std::lock_guard guard(libdriver_logger_lock);
  fx_logger_t* logger = fx_log_get_logger();
  return fx_logger_get_min_severity(logger) <= flag;
}

extern "C" void driver_logvf_internal(const zx_driver_t* drv, fx_log_severity_t flag,
                                      const char* tag, const char* file, int line, const char* msg,
                                      va_list args) {
  std::lock_guard guard(libdriver_logger_lock);
  fx_logger_t* logger = fx_log_get_logger();
  fx_logger_logvf_with_source(logger, flag, tag, file, line, msg, args);
}

extern "C" void driver_logf_internal(const zx_driver_t* drv, fx_log_severity_t flag,
                                     const char* tag, const char* file, int line, const char* msg,
                                     ...) {
  // The libdriver_logger_lock will be locked in `driver_logvf_internal`.
  va_list args;
  va_start(args, msg);
  driver_logvf_internal(drv, flag, tag, file, line, msg, args);
  va_end(args);
}

__EXPORT
__WEAK zx_driver_rec __zircon_driver_rec__ = {
    .ops = {},
    .driver = {},
};
