// 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 <assert.h>
#include <endian.h>
#include <unistd.h>

#include <cassert>
#include <limits>
#include <memory>
#include <vector>

#include "src/graphics/examples/vkproto/common/command_buffers.h"
#include "src/graphics/examples/vkproto/common/debug_utils_messenger.h"
#include "src/graphics/examples/vkproto/common/graphics_pipeline.h"
#include "src/graphics/examples/vkproto/common/image_view.h"
#include "src/graphics/examples/vkproto/common/instance.h"
#include "src/graphics/examples/vkproto/common/physical_device.h"
#include "src/graphics/examples/vkproto/common/readback.h"
#include "src/graphics/examples/vkproto/common/render_pass.h"
#ifdef __Fuchsia__
#include "src/graphics/examples/vkproto/fuchsia/fuchsia_surface.h"
#else
#include "src/graphics/examples/vkproto/glfw/glfw_surface.h"
#endif
#include "src/graphics/examples/vkproto/common/swapchain.h"
#include "src/graphics/examples/vkproto/common/utils.h"

#include <vulkan/vulkan.hpp>

#if USE_GLFW
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#endif

static bool DrawFrame(const vkp::Device& vkp_device, const vkp::Swapchain& swap_chain,
                      const vkp::CommandBuffers& command_buffers,
                      const std::vector<vk::UniqueFence>& fences);

static bool DrawOffscreenFrame(const vkp::Device& vkp_device,
                               const vkp::CommandBuffers& command_buffers, const vk::Fence& fence);

#if USE_GLFW
void glfwErrorCallback(int error, const char* description) {
  fprintf(stderr, "glfwErrorCallback: %d : %s\n", error, description);
}

static void glfwFramebufferResizeCallback(GLFWwindow* window, int width, int height) {
  // TODO(rosasco): Add ability to recreate swapchain here. Define new struct with all
  //                required dependencies to rebuild the swapchain called SwapchainDeps.
  //                Call glfwSetWindowUserPointer(window, swapchain_deps) in main below, then:
  //                auto swapchain_deps =
  //                    reinterpret_cast<SwapchainDeps*>(glfwGetWindowUserPointer(window));
  fprintf(stderr, "ERROR: Window resize not implemented.\n");
  exit(1);
}
#endif

int main(int argc, char* argv[]) {
  const bool offscreen = (argc == 2 && !strcmp(argv[1], "-offscreen"));
  printf("Is Offscreen: %s\n", offscreen ? "yes" : "no");

  // INSTANCE
  const bool kEnableValidation = true;
  vkp::Instance vkp_instance(kEnableValidation);
  RTN_IF_MSG(1, !vkp_instance.Init(), "Instance Initialization Failed.\n");
  std::shared_ptr<vk::Instance> instance = vkp_instance.shared();

  // DEBUG UTILS MESSENGER
  vkp::DebugUtilsMessenger vkp_debug_messenger(instance);
  RTN_IF_MSG(1, !vkp_debug_messenger.Init(), "Debug messenger initialization failed");

#if USE_GLFW
  GLFWwindow* window = nullptr;
  if (!offscreen) {
    glfwInit();
    glfwSetErrorCallback(glfwErrorCallback);
    RTN_IF_MSG(1, !glfwVulkanSupported(), "glfwVulkanSupported has returned false.\n");
    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    window = glfwCreateWindow(1024, 768, "VkProto", nullptr, nullptr);
    RTN_IF_MSG(1, !window, "glfwCreateWindow failed.\n");
    glfwSetFramebufferSizeCallback(window, glfwFramebufferResizeCallback);
  }
#endif

  // SURFACE
  std::shared_ptr<vkp::Surface> vkp_surface;
  if (!offscreen) {
#if USE_GLFW
    vkp_surface = std::make_shared<vkp::GlfwSurface>(instance, window);
#else
    vkp_surface = std::make_shared<vkp::FuchsiaSurface>(instance);
#endif
    RTN_IF_MSG(1, !vkp_surface->Init(), "Surface initialization failed\n");
  }

  VkSurfaceKHR surface = vkp_surface ? vkp_surface->get() : nullptr;

  // PHYSICAL DEVICE
  vkp::PhysicalDevice vkp_physical_device(instance, surface);
  RTN_IF_MSG(1, !vkp_physical_device.Init(), "Physical device initialization failed\n");
  const vk::PhysicalDevice& physical_device = vkp_physical_device.get();

  // LOGICAL DEVICE
  auto vkp_device = vkp::Device(physical_device, surface);
  RTN_IF_MSG(1, !vkp_device.Init(), "Logical device initialization failed\n");
  std::shared_ptr<vk::Device> device = vkp_device.shared();

  vk::Format image_format;
  vk::Extent2D extent;
  std::shared_ptr<vkp::Swapchain> vkp_swap_chain;

  // The number of image views added in either the offscreen or onscreen logic
  // blocks below controls the number of framebuffers, command buffers, fences
  // and signaling semaphores created subsequently.
  std::vector<vk::ImageView> image_views;
  std::shared_ptr<vkp::ImageView> vkp_offscreen_image_view;
  if (offscreen) {
    // IMAGE VIEW
    vkp_offscreen_image_view = std::make_shared<vkp::ImageView>(device, physical_device);
    RTN_IF_MSG(1, !vkp_offscreen_image_view->Init(), "Image View initialization failed\n");
    image_format = vkp_offscreen_image_view->format();
    extent = vkp_offscreen_image_view->extent();
    image_views.emplace_back(vkp_offscreen_image_view->get());
  } else {
    // SWAP CHAIN
    vkp_swap_chain = std::make_shared<vkp::Swapchain>(physical_device, device, surface);
    RTN_IF_MSG(1, !vkp_swap_chain->Init(), "Swap chain initialization failed\n");

    image_format = vkp_swap_chain->image_format();
    extent = vkp_swap_chain->extent();
    const auto& swap_chain_image_views = vkp_swap_chain->image_views();
    for (auto& view : swap_chain_image_views) {
      image_views.emplace_back(*view);
    }
  }

  // RENDER PASS
  auto vkp_render_pass = std::make_shared<vkp::RenderPass>(device, image_format, offscreen);
  RTN_IF_MSG(1, !vkp_render_pass->Init(), "Render pass initialization failed\n");

  // GRAPHICS PIPELINE
  auto vkp_pipeline = std::make_unique<vkp::GraphicsPipeline>(device, extent, vkp_render_pass);
  RTN_IF_MSG(1, !vkp_pipeline->Init(), "Graphics pipeline initialization failed\n");

  // FRAMEBUFFER
  auto vkp_framebuffers =
      std::make_unique<vkp::Framebuffers>(device, extent, vkp_render_pass->get(), image_views);
  RTN_IF_MSG(1, !vkp_framebuffers->Init(), "Framebuffer Initialization Failed.\n");

  // COMMAND POOL
  auto vkp_command_pool =
      std::make_shared<vkp::CommandPool>(device, vkp_device.queue_family_index());
  RTN_IF_MSG(1, !vkp_command_pool->Init(), "Command Pool Initialization Failed.\n");

  // COMMAND BUFFER
  auto vkp_command_buffers = std::make_unique<vkp::CommandBuffers>(
      vkp_device.shared(), vkp_command_pool, vkp_framebuffers->framebuffers(), vkp_pipeline->get(),
      vkp_render_pass->get(), extent);
  RTN_IF_MSG(1, !vkp_command_buffers->Init(), "Command buffer initialization.\n");

  // Offscreen drawing submission fence.
  const vk::FenceCreateInfo fence_info(vk::FenceCreateFlagBits::eSignaled);
  auto [r_offscren_fence, offscreen_fence] = device->createFenceUnique(fence_info);
  RTN_IF_VKH_ERR(1, r_offscren_fence, "Offscreen submission fence.\n");

  // Onscreen drawing submission fences.
  // There is a 1/1/1 mapping between swapchain image view / command buffer /
  // fence.
  std::vector<vk::UniqueFence> fences;
  for (size_t i = 0; i < image_views.size(); i++) {
    auto [r_fence, fence] = device->createFenceUnique(fence_info);
    RTN_IF_VKH_ERR(1, r_fence, "Onscreen submission fence.\n");
    fences.emplace_back(std::move(fence));
  }

#if USE_GLFW
  if (offscreen) {
    DrawOffscreenFrame(vkp_device, *vkp_command_buffers, offscreen_fence.get());
  } else {
    while (!glfwWindowShouldClose(window)) {
      glfwPollEvents();
      DrawFrame(vkp_device, *vkp_swap_chain, *vkp_command_buffers, fences);
    }
  }
#else
  if (offscreen) {
    DrawOffscreenFrame(vkp_device, *vkp_command_buffers, offscreen_fence.get());
  } else {
    DrawFrame(vkp_device, *vkp_swap_chain, *vkp_command_buffers, fences);
  }
  sleep(3);
#endif
  RTN_IF_VKH_ERR(1, device->waitIdle(), "waitIdle\n");

  if (offscreen) {
    // READBACK
    std::vector<uint32_t> output_pixels(1);
    vkp::ReadPixels(physical_device, *device, *(vkp_offscreen_image_view->image()), extent,
                    vkp_command_pool->get(), vkp_device.queue(), vk::Extent2D{1, 1}, vk::Offset2D{},
                    &output_pixels);
    uint32_t output_pixel = htole32(output_pixels[0]);
    printf("Clear Color Read: %02x,%02x,%02x,%02x\n", (uint8_t)(output_pixel >> 0) & 0xFF,
           (uint8_t)(output_pixel >> 8) & 0xFF, (uint8_t)(output_pixel >> 16) & 0xFF,
           (uint8_t)(output_pixel >> 24) & 0xFF);
  }

#if USE_GLFW
  if (!offscreen) {
    glfwDestroyWindow(window);
    glfwTerminate();
  }
#endif

  return 0;
}

bool DrawFrame(const vkp::Device& vkp_device, const vkp::Swapchain& vkp_swap_chain,
               const vkp::CommandBuffers& vkp_command_buffers,
               const std::vector<vk::UniqueFence>& fences) {
  // Compact variables for readability derived from |current_frame|.
  const vk::Device& device = vkp_device.get();

  auto [r_image_available_semaphore, image_available_semaphore] =
      device.createSemaphore(vk::SemaphoreCreateInfo{});
  RTN_IF_VKH_ERR(false, r_image_available_semaphore, "Image available semaphore.\n");

  auto [r_render_finished_semaphore, render_finished_semaphore] =
      device.createSemaphore(vk::SemaphoreCreateInfo{});
  RTN_IF_VKH_ERR(false, r_render_finished_semaphore, "Render finished semaphore.\n");

  // Obtain next swap chain image in which to draw.
  // The timeout makes this a blocking call if no swapchain images, and
  // therefore command buffers, are available so there is no need to wait for a
  // submission fence before calling acquireNextImageKHR().
  auto [r_acquire, swapchain_image_index] =
      device.acquireNextImageKHR(vkp_swap_chain.get(), std::numeric_limits<uint64_t>::max(),
                                 image_available_semaphore, nullptr);
  RTN_IF_VKH_ERR(false, r_acquire, "Acquire swapchain image.\n");

  // Define stage that |image_available_semaphore| is waiting on.
  const vk::PipelineStageFlags image_available_wait_stage =
      vk::PipelineStageFlagBits::eColorAttachmentOutput;

  vk::CommandBuffer command_buffer =
      vkp_command_buffers.command_buffers()[swapchain_image_index].get();

  vk::SubmitInfo submit_info;
  submit_info.waitSemaphoreCount = 1;
  submit_info.pWaitSemaphores = &image_available_semaphore;
  submit_info.pWaitDstStageMask = &image_available_wait_stage;
  submit_info.commandBufferCount = 1;
  submit_info.pCommandBuffers = &command_buffer;
  submit_info.signalSemaphoreCount = 1;
  submit_info.pSignalSemaphores = &render_finished_semaphore;

  // No guarantees that we're done with the acquired swap chain image and
  // therefore the command buffer we're about to use so wait on the command
  // buffer's fence.
  const vk::Fence& fence = fences[swapchain_image_index].get();
  RTN_IF_VKH_ERR(false,
                 device.waitForFences(1, &fence, VK_TRUE, std::numeric_limits<uint64_t>::max()),
                 "waitForFences\n");
  RTN_IF_VKH_ERR(false, device.resetFences(1, &fence), "resetFences failed\n");

  RTN_IF_VKH_ERR(false, vkp_device.queue().submit(1, &submit_info, fence),
                 "Failed to onscreen submit command buffer.\n");

  vk::PresentInfoKHR present_info;
  present_info.waitSemaphoreCount = 1;
  present_info.pWaitSemaphores = &render_finished_semaphore;
  present_info.swapchainCount = 1;
  present_info.setPSwapchains(&(vkp_swap_chain.get()));
  present_info.pImageIndices = &swapchain_image_index;

  RTN_IF_VKH_ERR(false, vkp_device.queue().presentKHR(&present_info), "presentKHR failed\n");
  RTN_IF_VKH_ERR(false, vkp_device.queue().waitIdle(), "queue waitIdle failed\n");

  device.destroySemaphore(render_finished_semaphore);
  device.destroySemaphore(image_available_semaphore);

  return true;
}

bool DrawOffscreenFrame(const vkp::Device& vkp_device,
                        const vkp::CommandBuffers& vkp_command_buffers, const vk::Fence& fence) {
  vk::CommandBuffer command_buffer = vkp_command_buffers.command_buffers()[0].get();
  vk::SubmitInfo submit_info;
  submit_info.commandBufferCount = 1;
  submit_info.pCommandBuffers = &command_buffer;

  // Wait for any outstanding command buffers to be processed.
  const vk::Device& device = vkp_device.get();
  RTN_IF_VKH_ERR(false,
                 device.waitForFences(1, &fence, VK_TRUE, std::numeric_limits<uint64_t>::max()),
                 "waitForFences failed\n");
  RTN_IF_VKH_ERR(false, device.resetFences(1, &fence), "resetFences failed\n");

  RTN_IF_VKH_ERR(false, vkp_device.queue().submit(1, &submit_info, fence),
                 "Failed to offscreen submit command buffer.\n");
  return true;
}
