// 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/fdio/fdio.h>
#include <lib/zx/channel.h>

#include <cstdio>
#include <string>

#include <vulkan/vk_icd.h>
#include <vulkan/vulkan.h>

// This file contains a fake Vulkan ICD that implements everything up to and including
// vkCreateInstance.

VKAPI_ATTR __attribute__((visibility("default"))) VkResult VKAPI_CALL
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pVersion) {
  fprintf(stderr, "Got icd Negotiate loader ICD interface version\n");
  *pVersion = 3;

  return VK_SUCCESS;
}

namespace {

bool open_in_namespace_callback_initialized = false;
struct Instance {
  Instance() : loader_magic(ICD_LOADER_MAGIC) {}

  // Instance is a dispatchable object, and the loader uses the first 8 bytes as a pointer. See
  // https://github.com/KhronosGroup/Vulkan-Loader/blob/master/loader/LoaderAndLayerInterface.md#icd-dispatchable-object-creation
  uintptr_t loader_magic;
};

VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
                                                const VkAllocationCallbacks* pAllocator,
                                                VkInstance* pInstance) {
  // Check that the open in namespace proc was set and was valid.
  if (!open_in_namespace_callback_initialized)
    return VK_ERROR_INITIALIZATION_FAILED;
  *pInstance = reinterpret_cast<VkInstance>(new Instance);
  return VK_SUCCESS;
}

VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
    const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties) {
  *pPropertyCount = 0;
  return VK_SUCCESS;
}

VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance,
                                             const VkAllocationCallbacks* pAllocator) {
  delete reinterpret_cast<Instance*>(instance);
}

VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion(uint32_t* pApiVersion) {
  *pApiVersion = VK_API_VERSION_1_0;
  return VK_SUCCESS;
}

VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
                                                       VkPhysicalDeviceFeatures* pFeatures) {}

VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties(
    VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties) {}

VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties(
    VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling,
    VkImageUsageFlags usage, VkImageCreateFlags flags,
    VkImageFormatProperties* pImageFormatProperties) {
  return VK_SUCCESS;
}

VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
                                                         VkPhysicalDeviceProperties* pProperties) {}

VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(
    VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount,
    VkQueueFamilyProperties* pQueueFamilyProperties) {}

VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(
    VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties) {}

VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* pName) {
  return nullptr;
}

VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice,
                                              const VkDeviceCreateInfo* pCreateInfo,
                                              const VkAllocationCallbacks* pAllocator,
                                              VkDevice* pDevice) {
  return VK_ERROR_INITIALIZATION_FAILED;
}

// Only the bare minimum Vulkan 1.0 core entrypoints are implemented. These are just enough for
// vkCreateInstance to succeed.
#define DEF_FUNCTION(name) \
  { #name, reinterpret_cast < PFN_vkVoidFunction>(name) }
struct FunctionTable {
  std::string name;
  PFN_vkVoidFunction function;
} functions[] = {
    DEF_FUNCTION(vkCreateInstance),
    DEF_FUNCTION(vkDestroyInstance),
    DEF_FUNCTION(vkEnumerateInstanceVersion),
    DEF_FUNCTION(vkEnumerateInstanceExtensionProperties),
    DEF_FUNCTION(vkEnumeratePhysicalDevices),
    DEF_FUNCTION(vkGetPhysicalDeviceFeatures),
    DEF_FUNCTION(vkGetPhysicalDeviceFormatProperties),
    DEF_FUNCTION(vkGetPhysicalDeviceImageFormatProperties),
    DEF_FUNCTION(vkGetPhysicalDeviceProperties),
    DEF_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties),
    DEF_FUNCTION(vkGetPhysicalDeviceMemoryProperties),
    DEF_FUNCTION(vkGetDeviceProcAddr),
    DEF_FUNCTION(vkCreateDevice),
    DEF_FUNCTION(vkEnumerateDeviceExtensionProperties),
    DEF_FUNCTION(vkGetPhysicalDeviceSparseImageFormatProperties),
};

#undef DEF_FUNCTION

}  // namespace

VKAPI_ATTR __attribute__((visibility("default"))) PFN_vkVoidFunction VKAPI_CALL
vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName) {
  for (auto& function : functions) {
    if (function.name == pName)
      return function.function;
  }
  return nullptr;
}

VKAPI_ATTR __attribute__((visibility("default"))) PFN_vkVoidFunction VKAPI_CALL
vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName) {
  return nullptr;
}

extern "C" {
typedef VkResult(VKAPI_PTR* PFN_vkOpenInNamespaceAddr)(const char* pName, uint32_t handle);
VKAPI_ATTR void VKAPI_CALL vk_icdInitializeOpenInNamespaceCallback(PFN_vkOpenInNamespaceAddr addr);
}

VKAPI_ATTR __attribute__((visibility("default"))) void VKAPI_CALL
vk_icdInitializeOpenInNamespaceCallback(PFN_vkOpenInNamespaceAddr open_in_namespace_addr) {
  zx::channel server_end, client_end;
  zx::channel::create(0, &server_end, &client_end);

  // A hermetic ICD shouldn't try to access to anything from the loader service.
  if (!getenv("HERMETIC_ICD")) {
    // ConnectToDeviceFs in the service provider should connect the device fs to /pkg/data.
    VkResult result =
        open_in_namespace_addr("/loader-gpu-devices/libvulkan_fake.json", server_end.release());
    if (result != VK_SUCCESS) {
      fprintf(stderr, "Opening libvulkan_fake.json failed with error %d\n", result);
      return;
    }

    fdio_t* fdio;
    zx_status_t status = fdio_create(client_end.release(), &fdio);
    if (status != ZX_OK) {
      fprintf(stderr, "fdio create failed with status %d\n", status);
      return;
    }

    int fd = fdio_bind_to_fd(fdio, -1, 0);
    if (fd < 0) {
      fprintf(stderr, "fdio_bind_to_fd failed\n");
      return;
    }
  }

  open_in_namespace_callback_initialized = true;
}
