// Copyright 2018 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 "vulkan_instance.h"

#include <vector>

#include "utils.h"
#include "vulkan_layer.h"

namespace {

static const std::vector<const char *> s_required_props = {
    VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
    VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
    VK_KHR_SURFACE_EXTENSION_NAME,
    VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
#ifdef __Fuchsia__
    VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME,
#endif
};

static const std::vector<const char *> s_desired_props = {
    VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
};

static void PrintProps(const std::vector<const char *> &props) {
  for (const auto &prop : props) {
    printf("\t%s\n", prop);
  }
  printf("\n");
}

#if USE_GLFW
std::vector<const char *> GetExtensionsGLFW() {
  uint32_t num_extensions = 0;
  const char **glfw_extensions;
  glfw_extensions = glfwGetRequiredInstanceExtensions(&num_extensions);
  std::vector<const char *> extensions(glfw_extensions, glfw_extensions + num_extensions);
  extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);

  return extensions;
}
#else
std::vector<const char *> GetExtensions_Private(std::vector<const char *> *layers) {
  const char *kMagmaLayer = "VK_LAYER_FUCHSIA_imagepipe_swapchain_fb";

  std::vector<const char *> extensions;
  std::vector<std::string> missing_props;

  if (!FindMatchingProperties(s_required_props, vkp::INSTANCE_EXT_PROP, nullptr /* device */,
                              kMagmaLayer, &missing_props)) {
    extensions.insert(extensions.end(), s_required_props.begin(), s_required_props.end());
  }

  return extensions;
}
#endif

}  // namespace

VulkanInstance::~VulkanInstance() { initialized_ = false; }

#if USE_GLFW
bool VulkanInstance::Init(bool enable_validation, GLFWwindow *window) {
  window_ = window;
#else
bool VulkanInstance::Init(bool enable_validation) {
#endif
  if (enable_validation && !VulkanLayer::CheckValidationLayerSupport()) {
    RTN_MSG(false, "Validation layers requested, but not available!");
  }

  // Application Info
  vk::ApplicationInfo app_info;
  app_info.apiVersion = VK_MAKE_VERSION(1, 0, 0);
  app_info.pApplicationName = "VkPrimer";
  app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
  app_info.pEngineName = "No Engine";
  app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0);

  // Instance Create Info
  vk::InstanceCreateInfo create_info;
  create_info.pApplicationInfo = &app_info;

  // Extensions
  extensions_ = GetExtensions();
  VulkanLayer::AppendRequiredInstanceExtensions(&extensions_);

  create_info.enabledExtensionCount = static_cast<uint32_t>(extensions_.size());
  create_info.ppEnabledExtensionNames = extensions_.data();

  // Layers
  VulkanLayer::AppendRequiredInstanceLayers(&layers_);

  if (enable_validation) {
    VulkanLayer::AppendValidationInstanceLayers(&layers_);
  }

  create_info.enabledLayerCount = static_cast<uint32_t>(layers_.size());
  create_info.ppEnabledLayerNames = layers_.data();

  fprintf(stderr, "Enabled Instance Extensions:\n");
  PrintProps(extensions_);

  fprintf(stderr, "Enabled layers:\n");
  for (auto &layer : layers_) {
    fprintf(stderr, "\t%s\n", layer);
  }
  fprintf(stderr, "\n");

  auto rv = vk::createInstanceUnique(create_info);
  if (vk::Result::eSuccess != rv.result) {
    RTN_MSG(false, "VK Error: 0x%x - Failed to create instance.", rv.result);
  }
  instance_ = std::move(rv.value);

  initialized_ = true;
  return true;
}

std::vector<const char *> VulkanInstance::GetExtensions() {
#if USE_GLFW
  extensions_ = GetExtensionsGLFW();
#else
  extensions_ = GetExtensions_Private(&layers_);
#endif

  return extensions_;
}

const vk::UniqueInstance &VulkanInstance::instance() const { return instance_; }
