// 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 "swapchain.h"

#include <limits>
#include <set>
#include <string>
#include <unordered_map>

#include "src/graphics/examples/vkproto/common/utils.h"

namespace {

vk::SurfaceFormatKHR ChooseSwapSurfaceFormat(
    const std::vector<vk::SurfaceFormatKHR>& available_formats) {
  if (available_formats.size() == 1 && available_formats[0].format == vk::Format::eUndefined) {
    return {vk::Format::eB8G8R8A8Unorm, vk::ColorSpaceKHR::eSrgbNonlinear};
  }

  for (const auto& available_format : available_formats) {
    if (available_format.format == vk::Format::eB8G8R8A8Unorm &&
        available_format.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear) {
      return available_format;
    }
  }

  return available_formats[0];
}

vk::PresentModeKHR ChooseSwapPresentMode(
    const std::vector<vk::PresentModeKHR>& available_present_modes) {
  std::unordered_map<vk::PresentModeKHR, int> kPresentModePriorities = {
      {vk::PresentModeKHR::eFifo, 0},
      {vk::PresentModeKHR::eMailbox, 1},
      {vk::PresentModeKHR::eImmediate, 2},
      {vk::PresentModeKHR::eFifoRelaxed, 3},
  };

  const vk::PresentModeKHR kLastPresentMode = vk::PresentModeKHR::eFifoRelaxed;
  vk::PresentModeKHR best_mode = kLastPresentMode;
  for (const auto& present_mode : available_present_modes) {
    if (kPresentModePriorities[present_mode] < kPresentModePriorities[best_mode]) {
      best_mode = present_mode;
    }
  }

  RTN_IF_MSG(best_mode, (best_mode == kLastPresentMode), "Unable to find usable VkPresentMode.\n");

  return best_mode;
}

vk::Extent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) {
  if (capabilities.currentExtent.width != std::numeric_limits<uint32_t>::max()) {
    return capabilities.currentExtent;
  } else {
    vk::Extent2D extent = {1024, 768};
    extent.width = std::max(capabilities.minImageExtent.width,
                            std::min(capabilities.maxImageExtent.width, extent.width));
    extent.height = std::max(capabilities.minImageExtent.height,
                             std::min(capabilities.maxImageExtent.height, extent.height));

    return extent;
  }
}

bool CreateImageViews(const vk::Device device, const vk::Format& image_format,
                      const std::vector<vk::Image> images,
                      std::vector<vk::UniqueImageView>* image_views) {
  vk::ImageSubresourceRange range;
  range.aspectMask = vk::ImageAspectFlagBits::eColor;
  range.layerCount = 1;
  range.levelCount = 1;

  vk::ImageViewCreateInfo image_view_info;
  image_view_info.format = image_format;
  image_view_info.subresourceRange = range;
  image_view_info.viewType = vk::ImageViewType::e2D;
  for (const auto& image : images) {
    image_view_info.image = image;

    auto [r_image_view, image_view] = device.createImageViewUnique(image_view_info);
    RTN_IF_VKH_ERR(false, r_image_view, "Failed to create image view.\n");
    image_views->emplace_back(std::move(image_view));
  }
  return true;
}

}  // namespace

namespace vkp {

Swapchain::Swapchain(const vk::PhysicalDevice phys_device, std::shared_ptr<vk::Device> device,
                     const VkSurfaceKHR& surface)
    : initialized_(false), device_(device), surface_(surface) {
  phys_device_ = std::make_unique<vk::PhysicalDevice>(phys_device);
}

bool Swapchain::Init() {
  RTN_IF_MSG(false, initialized_, "Swapchain is already initialized.\n");
  RTN_IF_MSG(false, !device_, "Device must be initialized.\n");

  Swapchain::Info info;
  QuerySwapchainSupport(*phys_device_, surface_, &info);
  vk::SurfaceFormatKHR surface_format = ChooseSwapSurfaceFormat(info.formats);
  vk::PresentModeKHR present_mode = ChooseSwapPresentMode(info.present_modes);
  extent_ = ChooseSwapExtent(info.capabilities);

  uint32_t num_images = info.capabilities.minImageCount + 1;
  if (info.capabilities.maxImageCount > 0 && num_images > info.capabilities.maxImageCount) {
    num_images = info.capabilities.maxImageCount;
  }

  vk::SwapchainCreateInfoKHR swapchain_info;
  swapchain_info.clipped = VK_TRUE;
  swapchain_info.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque;
  swapchain_info.minImageCount = num_images;
  swapchain_info.imageArrayLayers = 1;
  swapchain_info.imageColorSpace = surface_format.colorSpace;
  swapchain_info.imageExtent = extent_;
  swapchain_info.imageFormat = surface_format.format;
  swapchain_info.imageSharingMode = vk::SharingMode::eExclusive;
  swapchain_info.imageUsage = vk::ImageUsageFlagBits::eColorAttachment;
  swapchain_info.presentMode = present_mode;
  swapchain_info.preTransform = info.capabilities.currentTransform;
  swapchain_info.surface = surface_;

  auto [r_swapchain, swapchain] = device_->createSwapchainKHRUnique(swapchain_info);
  RTN_IF_VKH_ERR(false, r_swapchain, "Failed to create swap chain.\n");
  swap_chain_ = std::move(swapchain);

  auto [r_images, images] = device_->getSwapchainImagesKHR(*swap_chain_);
  RTN_IF_VKH_ERR(false, r_images, "Failed to get swap chain images.\n");

  image_format_ = surface_format.format;

  if (!CreateImageViews(*device_, image_format_, images, &image_views_)) {
    RTN_MSG(false, "Failed to create image views.\n");
  }

  phys_device_.reset();
  initialized_ = true;
  return initialized_;
}

bool Swapchain::QuerySwapchainSupport(vk::PhysicalDevice phys_device, VkSurfaceKHR surface,
                                      Swapchain::Info* info) {
  RTN_IF_VKH_ERR(false, phys_device.getSurfaceCapabilitiesKHR(surface, &info->capabilities),
                 "Failed to get surface capabilities\n");

  auto [r_surface_formats, surface_formats] = phys_device.getSurfaceFormatsKHR(surface);
  RTN_IF_VKH_ERR(false, r_surface_formats, "Failed to get surface formats.\n");
  info->formats = surface_formats;

  auto [r_present_modes, present_modes] = phys_device.getSurfacePresentModesKHR(surface);
  RTN_IF_VKH_ERR(false, r_present_modes, "Failed to get present modes.\n");
  info->present_modes = present_modes;

  return true;
}

}  // namespace vkp
