// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_SWAPCHAIN_IMPL_VK_H_
#define FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_SWAPCHAIN_IMPL_VK_H_

#include <cstdint>
#include <memory>
#include <variant>

#include "flutter/fml/macros.h"
#include "impeller/renderer/backend/vulkan/vk.h"
#include "vulkan/vulkan_enums.hpp"

namespace impeller {

class Context;
class SwapchainImageVK;
class Surface;
struct FrameSynchronizer;

//------------------------------------------------------------------------------
/// @brief      An instance of a swapchain that does NOT adapt to going out of
///             date with the underlying surface. Errors will be indicated when
///             the next drawable is acquired from this implementation of the
///             swapchain. If the error is due the swapchain going out of date,
///             the caller must recreate another instance by optionally
///             stealing this implementations guts.
///
class SwapchainImplVK final
    : public std::enable_shared_from_this<SwapchainImplVK> {
 public:
  static std::shared_ptr<SwapchainImplVK> Create(
      const std::shared_ptr<Context>& context,
      vk::UniqueSurfaceKHR surface,
      vk::SwapchainKHR old_swapchain = VK_NULL_HANDLE,
      vk::SurfaceTransformFlagBitsKHR last_transform =
          vk::SurfaceTransformFlagBitsKHR::eIdentity);

  ~SwapchainImplVK();

  bool IsValid() const;

  struct AcquireResult {
    std::unique_ptr<Surface> surface;
    bool out_of_date = false;

    explicit AcquireResult(bool p_out_of_date = false)
        : out_of_date(p_out_of_date) {}

    explicit AcquireResult(std::unique_ptr<Surface> p_surface)
        : surface(std::move(p_surface)) {}
  };

  AcquireResult AcquireNextDrawable();

  vk::Format GetSurfaceFormat() const;

  vk::SurfaceTransformFlagBitsKHR GetLastTransform() const;

  std::shared_ptr<Context> GetContext() const;

  std::pair<vk::UniqueSurfaceKHR, vk::UniqueSwapchainKHR> DestroySwapchain();

 private:
  std::weak_ptr<Context> context_;
  vk::UniqueSurfaceKHR surface_;
  vk::Queue present_queue_ = {};
  vk::Format surface_format_ = vk::Format::eUndefined;
  vk::UniqueSwapchainKHR swapchain_;
  std::vector<std::shared_ptr<SwapchainImageVK>> images_;
  std::vector<std::unique_ptr<FrameSynchronizer>> synchronizers_;
  size_t current_frame_ = 0u;
  bool is_valid_ = false;
  size_t current_transform_poll_count_ = 0u;
  vk::SurfaceTransformFlagBitsKHR transform_if_changed_discard_swapchain_;

  SwapchainImplVK(const std::shared_ptr<Context>& context,
                  vk::UniqueSurfaceKHR surface,
                  vk::SwapchainKHR old_swapchain,
                  vk::SurfaceTransformFlagBitsKHR last_transform);

  bool Present(const std::shared_ptr<SwapchainImageVK>& image, uint32_t index);

  void WaitIdle() const;

  SwapchainImplVK(const SwapchainImplVK&) = delete;

  SwapchainImplVK& operator=(const SwapchainImplVK&) = delete;
};

}  // namespace impeller

#endif  // FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_SWAPCHAIN_IMPL_VK_H_
