// 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 <dlfcn.h>
#include <fuchsia/ui/composition/cpp/fidl.h>
#include <fuchsia/ui/composition/cpp/fidl_test_base.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fdio/directory.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/zx/channel.h>

#include <chrono>
#include <future>
#include <mutex>
#include <set>

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

#include "sdk/lib/ui/scenic/cpp/view_creation_tokens.h"
#include "src/lib/fsl/handles/object_info.h"

namespace {

constexpr uint32_t kVendorIDIntel = 0x8086;
uint64_t ZirconIdFromHandle(uint32_t handle) {
  zx_info_handle_basic_t info;
  zx_status_t status =
      zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
  if (status != ZX_OK)
    return 0;
  return info.koid;
}

VkPhysicalDeviceType GetVkPhysicalDeviceType(VkPhysicalDevice device) {
  VkPhysicalDeviceProperties properties;
  vkGetPhysicalDeviceProperties(device, &properties);
  return properties.deviceType;
}

uint32_t GetVkPhysicalDeviceVendorID(VkPhysicalDevice device) {
  VkPhysicalDeviceProperties properties;
  vkGetPhysicalDeviceProperties(device, &properties);
  return properties.vendorID;
}

// FakeFlatland runs async loop on its own thread to allow the test
// to use blocking Vulkan calls while present callbacks are processed.
class FakeFlatland : public fuchsia::ui::composition::testing::Allocator_TestBase,
                     public fuchsia::ui::composition::testing::Flatland_TestBase,
                     public fuchsia::ui::composition::testing::ParentViewportWatcher_TestBase {
 public:
  FakeFlatland(fidl::InterfaceRequest<fuchsia::ui::composition::Allocator> allocator_request,
               fidl::InterfaceRequest<fuchsia::ui::composition::Flatland> flatland_request,
               bool should_present)
      : loop_(&kAsyncLoopConfigNoAttachToCurrentThread),
        allocator_binding_(this, std::move(allocator_request), loop_.dispatcher()),
        flatland_binding_(this, std::move(flatland_request), loop_.dispatcher()),
        should_present_(should_present) {
    loop_.StartThread();
  }

  ~FakeFlatland() { loop_.Shutdown(); }

  void NotImplemented_(const std::string& name) override {
    fprintf(stderr, "NotImplemented: %s\n", name.c_str());
  }

  // |fuchsia::ui::composition::testing::Allocator|
  void RegisterBufferCollection(fuchsia::ui::composition::RegisterBufferCollectionArgs args,
                                RegisterBufferCollectionCallback callback) override {
    EXPECT_EQ(fuchsia::ui::composition::RegisterBufferCollectionUsage::DEFAULT, args.usage());
    auto [_, import_token_koid] = fsl::GetKoids(args.export_token().value.get());
    registered_koids.insert(import_token_koid);

    fuchsia::sysmem2::AllocatorSyncPtr sysmem_allocator;
    zx_status_t status = fdio_service_connect(
        "/svc/fuchsia.sysmem2.Allocator", sysmem_allocator.NewRequest().TakeChannel().release());
    EXPECT_EQ(status, ZX_OK);
    sysmem_allocator->SetDebugClientInfo(
        std::move(fuchsia::sysmem2::AllocatorSetDebugClientInfoRequest{}
                      .set_name(fsl::GetCurrentProcessName())
                      .set_id(fsl::GetCurrentProcessKoid())));

    fuchsia::sysmem2::BufferCollectionSyncPtr buffer_collection;
    status = sysmem_allocator->BindSharedCollection(
        std::move(fuchsia::sysmem2::AllocatorBindSharedCollectionRequest{}
                      .set_token(fidl::InterfaceHandle<fuchsia::sysmem2::BufferCollectionToken>(
                          args.mutable_buffer_collection_token()->TakeChannel()))
                      .set_buffer_collection_request(buffer_collection.NewRequest())));
    EXPECT_EQ(status, ZX_OK);

    status = buffer_collection->SetConstraints(
        fuchsia::sysmem2::BufferCollectionSetConstraintsRequest{});
    EXPECT_EQ(status, ZX_OK);

    status = buffer_collection->Release();
    EXPECT_EQ(status, ZX_OK);
  }

  // |fuchsia::ui::composition::testing::Flatland|
  void SetDebugName(std::string debug_name) override {
    // Do nothing.
  }

  // |fuchsia::ui::composition::testing::Flatland|
  void CreateView2(fuchsia::ui::views::ViewCreationToken token,
                   fuchsia::ui::views::ViewIdentityOnCreation view_identity,
                   fuchsia::ui::composition::ViewBoundProtocols view_protocols,
                   fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
                       parent_viewport_watcher) override {
    // Do nothing.
  }

  // |fuchsia::ui::composition::testing::Flatland|
  void CreateImage(fuchsia::ui::composition::ContentId image_id,
                   fuchsia::ui::composition::BufferCollectionImportToken import_token,
                   uint32_t vmo_index,
                   fuchsia::ui::composition::ImageProperties properties) override {
    auto [import_token_koid, _] = fsl::GetKoids(import_token.value.get());
    EXPECT_TRUE(registered_koids.find(import_token_koid) != registered_koids.end());

    EXPECT_TRUE(registered_images.find(image_id.value) == registered_images.end());
    registered_images.insert(image_id.value);
  }

  // |fuchsia::ui::composition::testing::Flatland|
  void ReleaseImage(fuchsia::ui::composition::ContentId image_id) override {
    EXPECT_TRUE(registered_images.find(image_id.value) != registered_images.end());
    registered_images.erase(image_id.value);
  }

  // |fuchsia::ui::composition::testing::Flatland|
  void CreateTransform(fuchsia::ui::composition::TransformId transform_id) override {
    EXPECT_EQ(kRootTransform.value, transform_id.value);
  }

  // |fuchsia::ui::composition::testing::Flatland|
  void SetRootTransform(fuchsia::ui::composition::TransformId transform_id) override {
    EXPECT_EQ(kRootTransform.value, transform_id.value);
  }

  // |fuchsia::ui::composition::testing::Flatland|
  void SetImageDestinationSize(fuchsia::ui::composition::ContentId image_id,
                               fuchsia::math::SizeU size) override {
    EXPECT_TRUE(registered_images.find(image_id.value) != registered_images.end());
  }

  // |fuchsia::ui::composition::testing::Flatland|
  void SetContent(fuchsia::ui::composition::TransformId transform_id,
                  fuchsia::ui::composition::ContentId content_id) override {
    EXPECT_EQ(kRootTransform.value, transform_id.value);
    EXPECT_TRUE(registered_images.find(content_id.value) != registered_images.end());
    image_on_root_transform_ = content_id.value;
  }

  // |fuchsia::ui::composition::testing::Flatland|
  void Present(fuchsia::ui::composition::PresentArgs args) override {
    std::unique_lock<std::mutex> lock(mutex_);

    acquire_fences_.insert(ZirconIdFromHandle(args.acquire_fences()[0].get()));

    zx_signals_t pending;
    zx_status_t status = args.acquire_fences()[0].wait_one(
        ZX_EVENT_SIGNALED, zx::deadline_after(zx::sec(10)), &pending);

    if (status == ZX_OK) {
      if (should_present_) {
        if (!args.release_fences().empty()) {
          args.release_fences()[0].signal(0, ZX_EVENT_SIGNALED);
        }
        // Run OnNextFrameBegin callback.
        fuchsia::ui::composition::OnNextFrameBeginValues values;
        values.set_additional_present_credits(1);
        flatland_binding_.events().OnNextFrameBegin(std::move(values));

        // Run OnFramePresented callback.
        fuchsia::scenic::scheduling::FramePresentedInfo frame_presented_info;
        fuchsia::scenic::scheduling::PresentReceivedInfo received_info;
        frame_presented_info.presentation_infos.emplace_back(std::move(received_info));
        flatland_binding_.events().OnFramePresented(std::move(frame_presented_info));
      }
    }
    presented_.push_back({image_on_root_transform_, status});
  }

  uint32_t presented_count() {
    std::unique_lock<std::mutex> lock(mutex_);
    return static_cast<uint32_t>(presented_.size());
  }

  uint32_t acquire_fences_count() {
    std::unique_lock<std::mutex> lock(mutex_);
    return static_cast<uint32_t>(acquire_fences_.size());
  }

  struct Presented {
    uint64_t image_id;
    zx_status_t acquire_wait_status;
  };

 private:
  async::Loop loop_;
  fidl::Binding<fuchsia::ui::composition::Allocator> allocator_binding_;
  fidl::Binding<fuchsia::ui::composition::Flatland> flatland_binding_;

  const fuchsia::ui::composition::TransformId kRootTransform = {1};
  std::set<zx_koid_t> registered_koids;
  std::set<uint64_t> registered_images;
  uint64_t image_on_root_transform_ = 0;
  bool should_present_;
  std::mutex mutex_;
  std::vector<Presented> presented_;
  std::set<uint64_t> acquire_fences_;
};

void GetFakeFlatlandInjectedToLib(std::unique_ptr<FakeFlatland>* flatland, bool should_present) {
  zx::channel local_allocator_endpoint, remote_allocator_endpoint;
  ASSERT_EQ(ZX_OK, zx::channel::create(0, &local_allocator_endpoint, &remote_allocator_endpoint));
  zx::channel local_flatland_endpoint, remote_flatland_endpoint;
  ASSERT_EQ(ZX_OK, zx::channel::create(0, &local_flatland_endpoint, &remote_flatland_endpoint));

  // Inject it to vulkan swapchain lib.
  void* libvulkan = dlopen("VkLayer_image_pipe_swapchain.so", RTLD_NOW | RTLD_LOCAL);
  ASSERT_NE(libvulkan, nullptr);
  typedef bool (*imagepipe_initialize_service_channel_fn)(zx::channel, zx::channel);
  auto fn = reinterpret_cast<imagepipe_initialize_service_channel_fn>(
      dlsym(libvulkan, "imagepipe_initialize_service_channel"));
  ASSERT_NE(fn, nullptr);
  ASSERT_TRUE(fn(std::move(remote_allocator_endpoint), std::move(remote_flatland_endpoint)));

  *flatland =
      std::make_unique<FakeFlatland>(fidl::InterfaceRequest<fuchsia::ui::composition::Allocator>(
                                         std::move(local_allocator_endpoint)),
                                     fidl::InterfaceRequest<fuchsia::ui::composition::Flatland>(
                                         std::move(local_flatland_endpoint)),
                                     should_present);
}

}  // namespace

static VKAPI_ATTR VkBool32 VKAPI_CALL
debug_utils_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
                     VkDebugUtilsMessageTypeFlagsEXT messageTypes,
                     const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData);

class TestSwapchain {
 public:
  static constexpr uint32_t kSwapchainImageCount = 3;

  template <class T>
  void LoadProc(T* proc, const char* name) {
    auto get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
        vkGetInstanceProcAddr(vk_instance_, "vkGetDeviceProcAddr"));
    *proc = reinterpret_cast<T>(get_device_proc_addr(vk_device_, name));
  }

  TestSwapchain(std::vector<const char*> instance_layers, bool protected_memory)
      : protected_memory_(protected_memory) {
    std::vector<const char*> instance_ext{
        VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
        VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME,
        VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME};
    std::vector<const char*> device_ext{VK_KHR_SWAPCHAIN_EXTENSION_NAME};

    const VkValidationFeatureEnableEXT sync_validation =
        VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT;
    const VkValidationFeaturesEXT validation_features = {
        .sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
        .pNext = nullptr,
        .enabledValidationFeatureCount = 1,
        .pEnabledValidationFeatures = &sync_validation,
    };
    const VkApplicationInfo app_info = {
        .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
        .pNext = nullptr,
        .pApplicationName = "test",
        .applicationVersion = 0,
        .pEngineName = "test",
        .engineVersion = 0,
        .apiVersion = VK_MAKE_VERSION(1, 1, 0),
    };
    VkInstanceCreateInfo inst_info = {
        .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
        .pNext = &validation_features,
        .pApplicationInfo = &app_info,
        .enabledLayerCount = static_cast<uint32_t>(instance_layers.size()),
        .ppEnabledLayerNames = instance_layers.data(),
        .enabledExtensionCount = static_cast<uint32_t>(instance_ext.size()),
        .ppEnabledExtensionNames = instance_ext.data(),
    };

    VkResult result;
    result = vkCreateInstance(&inst_info, nullptr, &vk_instance_);
    if (result != VK_SUCCESS) {
      fprintf(stderr, "vkCreateInstance failed: %d\n", result);
      return;
    }

    uint32_t gpu_count = 1;
    std::vector<VkPhysicalDevice> physical_devices(gpu_count);
    result = vkEnumeratePhysicalDevices(vk_instance_, &gpu_count, physical_devices.data());
    if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
      fprintf(stderr, "vkEnumeratePhysicalDevices failed: %d\n", result);
      return;
    }
    vk_physical_device_ = physical_devices[0];

    VkPhysicalDeviceProtectedMemoryFeatures protected_memory_features = {
        .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,
        .pNext = nullptr,
        .protectedMemory = VK_FALSE,
    };
    if (protected_memory_) {
      VkPhysicalDeviceProperties properties;
      vkGetPhysicalDeviceProperties(vk_physical_device_, &properties);
      if (properties.apiVersion < VK_MAKE_VERSION(1, 1, 0)) {
        protected_memory_is_supported_ = false;
        fprintf(stderr, "Vulkan 1.1 is not supported by device\n");
        return;
      }

      PFN_vkGetPhysicalDeviceFeatures2 get_physical_device_features_2_ =
          reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2>(
              vkGetInstanceProcAddr(vk_instance_, "vkGetPhysicalDeviceFeatures2"));
      if (!get_physical_device_features_2_) {
        fprintf(stderr, "Failed to find vkGetPhysicalDeviceFeatures2\n");
        return;
      }
      VkPhysicalDeviceFeatures2 physical_device_features = {
          .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
          .pNext = &protected_memory_features};
      get_physical_device_features_2_(vk_physical_device_, &physical_device_features);
      protected_memory_is_supported_ = protected_memory_features.protectedMemory;
      if (!protected_memory_is_supported_) {
        fprintf(stderr, "Protected memory is not supported\n");
        return;
      }
    }

    auto pfnCreateDebugUtilsMessengerEXT = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>(
        vkGetInstanceProcAddr(vk_instance_, "vkCreateDebugUtilsMessengerEXT"));
    get_surface_support_khr_ = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceSupportKHR>(
        vkGetInstanceProcAddr(vk_instance_, "vkGetPhysicalDeviceSurfaceSupportKHR"));
    get_surface_caps2_khr_ = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR>(
        vkGetInstanceProcAddr(vk_instance_, "vkGetPhysicalDeviceSurfaceCapabilities2KHR"));

    VkDebugUtilsMessengerCreateInfoEXT callback = {
        .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
        .pNext = nullptr,
        .flags = 0,
        .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
        .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
                       VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
        .pfnUserCallback = debug_utils_callback,
        .pUserData = this};
    result = pfnCreateDebugUtilsMessengerEXT(vk_instance_, &callback, NULL, &messenger_cb_);
    if (result != VK_SUCCESS) {
      fprintf(stderr, "Failed to install debug callback\n");
      return;
    }
    float queue_priorities[1] = {0.0};
    VkDeviceQueueCreateInfo queue_create_info = {
        .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
        .pNext = nullptr,
        .flags = protected_memory_
                     ? static_cast<VkDeviceQueueCreateFlags>(VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT)
                     : 0,
        .queueFamilyIndex = 0,
        .queueCount = 1,
        .pQueuePriorities = queue_priorities};

    VkDeviceCreateInfo device_create_info = {
        .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
        .pNext = protected_memory_ ? &protected_memory_features : nullptr,
        .queueCreateInfoCount = 1,
        .pQueueCreateInfos = &queue_create_info,
        .enabledLayerCount = 0,
        .ppEnabledLayerNames = nullptr,
        .enabledExtensionCount = static_cast<uint32_t>(device_ext.size()),
        .ppEnabledExtensionNames = device_ext.data(),
        .pEnabledFeatures = nullptr};

    result = vkCreateDevice(vk_physical_device_, &device_create_info, nullptr, &vk_device_);
    if (result != VK_SUCCESS) {
      fprintf(stderr, "vkCreateDevice failed: %d\n", result);
      return;
    }

    VkCommandPoolCreateInfo pool_info = {
        .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
        .pNext = nullptr,
        .flags = protected_memory_ ? VK_COMMAND_POOL_CREATE_PROTECTED_BIT : 0u,
        .queueFamilyIndex = 0,
    };

    EXPECT_EQ(VK_SUCCESS, vkCreateCommandPool(vk_device_, &pool_info, nullptr, &vk_command_pool_));

    PFN_vkGetDeviceProcAddr get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
        vkGetInstanceProcAddr(vk_instance_, "vkGetDeviceProcAddr"));
    if (!get_device_proc_addr) {
      fprintf(stderr, "Failed to find vkGetDeviceProcAddr\n");
      return;
    }

    LoadProc(&create_swapchain_khr_, "vkCreateSwapchainKHR");
    LoadProc(&destroy_swapchain_khr_, "vkDestroySwapchainKHR");
    LoadProc(&get_swapchain_images_khr_, "vkGetSwapchainImagesKHR");
    LoadProc(&acquire_next_image_khr_, "vkAcquireNextImageKHR");
    LoadProc(&queue_present_khr_, "vkQueuePresentKHR");
    LoadProc(&get_device_queue2_, "vkGetDeviceQueue2");

    if (protected_memory_) {
      VkDeviceQueueInfo2 queue_info2 = {.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
                                        .pNext = nullptr,
                                        .flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,
                                        .queueFamilyIndex = 0,
                                        .queueIndex = 0};
      get_device_queue2_(vk_device_, &queue_info2, &vk_queue_);
    } else {
      vkGetDeviceQueue(vk_device_, 0, 0, &vk_queue_);
    }

    init_ = true;
  }

  ~TestSwapchain() {
    if (vk_command_pool_) {
      vkDestroyCommandPool(vk_device_, vk_command_pool_, nullptr);
    }
    if (messenger_cb_) {
      auto pfnDestroyDebugUtilsMessengerEXT = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT>(
          vkGetInstanceProcAddr(vk_instance_, "vkDestroyDebugUtilsMessengerEXT"));
      pfnDestroyDebugUtilsMessengerEXT(vk_instance_, messenger_cb_, nullptr);
    }

    if (vk_device_ != VK_NULL_HANDLE)
      vkDestroyDevice(vk_device_, nullptr);

    if (vk_instance_ != VK_NULL_HANDLE)
      vkDestroyInstance(vk_instance_, nullptr);
  }

  void ValidateSurfaceForDevice(VkSurfaceKHR surface) {
    VkSurfaceProtectedCapabilitiesKHR surface_protected_caps = {
        .sType = VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR,
        .pNext = nullptr,
    };
    VkSurfaceCapabilities2KHR surface_caps2 = {
        .sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR,
        .pNext = &surface_protected_caps,
    };
    VkPhysicalDeviceSurfaceInfo2KHR surface_info = {
        .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
        .pNext = nullptr,
        .surface = surface,
    };
    ASSERT_TRUE(get_surface_caps2_khr_);
    EXPECT_EQ(VK_SUCCESS,
              get_surface_caps2_khr_(vk_physical_device_, &surface_info, &surface_caps2));
    if (protected_memory_) {
      EXPECT_TRUE(surface_protected_caps.supportsProtected);
    }
    VkBool32 surface_supported = false;
    EXPECT_EQ(VK_SUCCESS, get_surface_support_khr_(vk_physical_device_, /*queue_family_index*/ 0,
                                                   surface, &surface_supported));
    EXPECT_TRUE(surface_supported);
  }

  std::vector<VkImage> GetSwapchainImages(VkSwapchainKHR swapchain) {
    uint32_t image_count = 0;
    EXPECT_EQ(VK_SUCCESS, get_swapchain_images_khr_(vk_device_, swapchain, &image_count, nullptr));
    EXPECT_EQ(image_count, kSwapchainImageCount);
    std::vector<VkImage> images(image_count);
    EXPECT_EQ(VK_SUCCESS,
              get_swapchain_images_khr_(vk_device_, swapchain, &image_count, images.data()));
    return images;
  }

  VkResult CreateSwapchainHelper(VkSurfaceKHR surface, VkFormat format, VkImageUsageFlags usage,
                                 VkSwapchainKHR* swapchain_out) {
    ValidateSurfaceForDevice(surface);
    VkSwapchainCreateInfoKHR create_info = {
        .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
        .pNext = nullptr,
        .flags = protected_memory_ ? VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR
                                   : static_cast<VkSwapchainCreateFlagsKHR>(0),
        .surface = surface,
        .minImageCount = kSwapchainImageCount,
        .imageFormat = format,
        .imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
        .imageExtent = {100, 100},
        .imageArrayLayers = 1,
        .imageUsage = usage,
        .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
        .queueFamilyIndexCount = 0,
        .pQueueFamilyIndices = nullptr,
        .preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
        .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
        .presentMode = VK_PRESENT_MODE_FIFO_KHR,
        .clipped = VK_TRUE,
        .oldSwapchain = VK_NULL_HANDLE,
    };

    VkResult result = create_swapchain_khr_(vk_device_, &create_info, nullptr, swapchain_out);
    if (result != VK_SUCCESS)
      return result;

    // Get Swapchain images to make the validation layers happy.
    GetSwapchainImages(*swapchain_out);
    return VK_SUCCESS;
  }

  void Surface(bool use_dynamic_symbol) {
    ASSERT_TRUE(init_);

    PFN_vkCreateImagePipeSurfaceFUCHSIA f_vkCreateImagePipeSurfaceFUCHSIA =
        use_dynamic_symbol
            ? reinterpret_cast<PFN_vkCreateImagePipeSurfaceFUCHSIA>(
                  vkGetInstanceProcAddr(vk_instance_, "vkCreateImagePipeSurfaceFUCHSIA"))
            : vkCreateImagePipeSurfaceFUCHSIA;
    ASSERT_TRUE(f_vkCreateImagePipeSurfaceFUCHSIA);

    zx::channel endpoint0, endpoint1;
    EXPECT_EQ(ZX_OK, zx::channel::create(0, &endpoint0, &endpoint1));

    VkImagePipeSurfaceCreateInfoFUCHSIA create_info = {
        .sType = VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA,
        .pNext = nullptr,
        .imagePipeHandle = endpoint0.release(),
    };
    VkSurfaceKHR surface;
    EXPECT_EQ(VK_SUCCESS,
              f_vkCreateImagePipeSurfaceFUCHSIA(vk_instance_, &create_info, nullptr, &surface));
    vkDestroySurfaceKHR(vk_instance_, surface, nullptr);
  }

  void CreateSwapchain(int num_swapchains, VkFormat format, VkImageUsageFlags usage) {
    ASSERT_TRUE(init_);

    GetFakeFlatlandInjectedToLib(&fake_flatland_, /*should_present=*/true);

    auto [view_token, viewport_token] = scenic::ViewCreationTokenPair::New();
    VkImagePipeSurfaceCreateInfoFUCHSIA create_info = {
        .sType = VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA,
        .pNext = nullptr,
        .imagePipeHandle = view_token.value.release(),
    };
    VkSurfaceKHR surface;
    EXPECT_EQ(VK_SUCCESS,
              vkCreateImagePipeSurfaceFUCHSIA(vk_instance_, &create_info, nullptr, &surface));

    for (int i = 0; i < num_swapchains; ++i) {
      VkSwapchainKHR swapchain;
      VkResult result = CreateSwapchainHelper(surface, format, usage, &swapchain);
      EXPECT_EQ(VK_SUCCESS, result);
      if (VK_SUCCESS == result) {
        destroy_swapchain_khr_(vk_device_, swapchain, nullptr);
      }
    }

    vkDestroySurfaceKHR(vk_instance_, surface, nullptr);
  }

  void TransitionLayout(VkImage image, VkImageLayout to) {
    VkCommandBuffer command_buffer;
    VkCommandBufferAllocateInfo alloc_info = {
        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
        .pNext = nullptr,
        .commandPool = vk_command_pool_,
        .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
        .commandBufferCount = 1,
    };
    EXPECT_EQ(VK_SUCCESS, vkAllocateCommandBuffers(vk_device_, &alloc_info, &command_buffer));
    VkCommandBufferBeginInfo begin_info = {
        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
        .pNext = nullptr,
        .flags = 0,
        .pInheritanceInfo = nullptr,
    };
    EXPECT_EQ(VK_SUCCESS, vkBeginCommandBuffer(command_buffer, &begin_info));
    VkImageMemoryBarrier image_barrer = {
        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
        .pNext = nullptr,
        .srcAccessMask = 0,
        .dstAccessMask = 0,
        .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
        .newLayout = to,
        .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
        .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
        .image = image,
        .subresourceRange = {.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                             .baseMipLevel = 0,
                             .levelCount = 1,
                             .baseArrayLayer = 0,
                             .layerCount = 1}};
    vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
                         VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
                         &image_barrer);
    VkProtectedSubmitInfo protected_submit = {.sType = VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO,
                                              .pNext = nullptr,
                                              .protectedSubmit = protected_memory_};
    VkSubmitInfo submit_info = {
        .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
        .pNext = &protected_submit,
        .waitSemaphoreCount = 0,
        .pWaitSemaphores = nullptr,
        .commandBufferCount = 1,
        .pCommandBuffers = &command_buffer,
        .signalSemaphoreCount = 0,
        .pSignalSemaphores = nullptr,
    };
    EXPECT_EQ(VK_SUCCESS, vkEndCommandBuffer(command_buffer));
    EXPECT_EQ(VK_SUCCESS, vkQueueSubmit(vk_queue_, 1, &submit_info, VK_NULL_HANDLE));
    EXPECT_EQ(VK_SUCCESS, vkQueueWaitIdle(vk_queue_));
    vkFreeCommandBuffers(vk_device_, vk_command_pool_, 1, &command_buffer);
  }

  VkInstance vk_instance_ = VK_NULL_HANDLE;
  VkPhysicalDevice vk_physical_device_ = VK_NULL_HANDLE;
  VkDevice vk_device_ = VK_NULL_HANDLE;
  VkCommandPool vk_command_pool_ = VK_NULL_HANDLE;
  VkQueue vk_queue_ = VK_NULL_HANDLE;
  VkDebugUtilsMessengerEXT messenger_cb_ = nullptr;
  PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR get_surface_caps2_khr_;
  PFN_vkGetPhysicalDeviceSurfaceSupportKHR get_surface_support_khr_;
  PFN_vkCreateSwapchainKHR create_swapchain_khr_;
  PFN_vkDestroySwapchainKHR destroy_swapchain_khr_;
  PFN_vkGetSwapchainImagesKHR get_swapchain_images_khr_;
  PFN_vkAcquireNextImageKHR acquire_next_image_khr_;
  PFN_vkQueuePresentKHR queue_present_khr_;
  PFN_vkGetDeviceQueue2 get_device_queue2_;
  std::unique_ptr<FakeFlatland> fake_flatland_;

  const bool protected_memory_ = false;
  bool init_ = false;
  bool protected_memory_is_supported_ = false;
  bool allows_validation_errors_ = false;
};

static VKAPI_ATTR VkBool32 VKAPI_CALL
debug_utils_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
                     VkDebugUtilsMessageTypeFlagsEXT messageTypes,
                     const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) {
  fprintf(stderr, "Got debug utils callback: %s\n", pCallbackData->pMessage);
  auto swapchain = static_cast<TestSwapchain*>(pUserData);
  EXPECT_TRUE(swapchain->allows_validation_errors_);
  return VK_FALSE;
}
using UseProtectedMemory = bool;
using WithCopy = bool;
using ValidationBeforeLayer = bool;

using ParamType = std::tuple<UseProtectedMemory, WithCopy, ValidationBeforeLayer>;

static std::string NameFromParam(const testing::TestParamInfo<ParamType>& info) {
  bool protected_mem = std::get<0>(info.param);
  bool with_copy = std::get<1>(info.param);
  bool validation_before = std::get<2>(info.param);
  return std::string() + (protected_mem ? "Protected" : "Unprotected") +
         (with_copy ? "Copy" : "NoCopy") +
         (validation_before ? "ValidationBefore" : "ValidationAfter");
}

class SwapchainTest : public ::testing::TestWithParam<ParamType> {
 protected:
  void SetUp() override {
    std::vector<const char*> instance_layers;
    // The copy swapchain doesn't pass validation, so skip this test.
    // TODO(https://fxbug.dev/42163978): Re-enable when swapchain is fixed.
    if (with_copy() && validation_before_layer()) {
      GTEST_SKIP();
    }
    if (with_copy()) {
      instance_layers.push_back("VK_LAYER_FUCHSIA_imagepipe_swapchain_copy");
    }
    if (validation_before_layer()) {
      instance_layers.push_back("VK_LAYER_KHRONOS_validation");
    }
    instance_layers.push_back("VK_LAYER_FUCHSIA_imagepipe_swapchain");
    // The copy swapchain doesn't pass validation, so don't enable validation when using it.
    // TODO(https://fxbug.dev/42163978): Re-enable when swapchain is fixed.
    if (!validation_before_layer() && !with_copy()) {
      instance_layers.push_back("VK_LAYER_KHRONOS_validation");
    }

    auto test = std::make_unique<TestSwapchain>(instance_layers, use_protected_memory());
    if (use_protected_memory() && !test->protected_memory_is_supported_) {
      GTEST_SKIP();
    }
    ASSERT_TRUE(test->init_);

    test_ = std::move(test);
  }

  void TearDown() override {
    for (auto& semaphore : single_use_semaphores_) {
      vkDestroySemaphore(test_->vk_device_, semaphore, nullptr);
    }
  }

  bool use_protected_memory() { return std::get<0>(GetParam()); }

  bool with_copy() { return std::get<1>(GetParam()); }

  bool validation_before_layer() { return std::get<2>(GetParam()); }

  VkSemaphore MakeSingleUseSemaphore() {
    VkSemaphore semaphore;
    VkSemaphoreCreateInfo semaphore_create_info{.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
    EXPECT_EQ(VK_SUCCESS,
              vkCreateSemaphore(test_->vk_device_, &semaphore_create_info, nullptr, &semaphore));
    single_use_semaphores_.push_back(semaphore);
    return semaphore;
  }

  std::unique_ptr<TestSwapchain> test_;
  std::vector<VkSemaphore> single_use_semaphores_;
};

TEST_P(SwapchainTest, Surface) { test_->Surface(false); }

TEST_P(SwapchainTest, SurfaceDynamicSymbol) { test_->Surface(true); }

TEST_P(SwapchainTest, Create) {
  test_->CreateSwapchain(1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
}

TEST_P(SwapchainTest, CreateTwice) {
  test_->CreateSwapchain(2, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
}

TEST_P(SwapchainTest, CreateForStorage) {
  // TODO(60853): STORAGE usage is currently not supported by FEMU Vulkan ICD.
  if (GetVkPhysicalDeviceType(test_->vk_physical_device_) == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) {
    GTEST_SKIP();
  }

  if (GetVkPhysicalDeviceVendorID(test_->vk_physical_device_) == kVendorIDIntel) {
    // TODO(https://fxbug.dev/42163990): STORAGE usage isn't supported by Intel.
    GTEST_SKIP();
  }

  test_->CreateSwapchain(1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_STORAGE_BIT);
}

TEST_P(SwapchainTest, CreateForRgbaStorage) {
  // TODO(60853): STORAGE usage is currently not supported by FEMU Vulkan ICD.
  if (GetVkPhysicalDeviceType(test_->vk_physical_device_) == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) {
    GTEST_SKIP();
  }
  test_->CreateSwapchain(1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_STORAGE_BIT);
}

TEST_P(SwapchainTest, CreateForSrgb) {
  test_->CreateSwapchain(1, VK_FORMAT_B8G8R8A8_SRGB, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
}

TEST_P(SwapchainTest, AcquireFence) {
  GetFakeFlatlandInjectedToLib(&test_->fake_flatland_, /*should_present=*/true);

  auto [view_token, viewport_token] = scenic::ViewCreationTokenPair::New();
  VkImagePipeSurfaceCreateInfoFUCHSIA create_info = {
      .sType = VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA,
      .pNext = nullptr,
      .imagePipeHandle = view_token.value.release(),
  };

  VkSurfaceKHR surface;
  EXPECT_EQ(VK_SUCCESS,
            vkCreateImagePipeSurfaceFUCHSIA(test_->vk_instance_, &create_info, nullptr, &surface));

  VkSwapchainKHR swapchain;
  EXPECT_EQ(VK_SUCCESS,
            test_->CreateSwapchainHelper(surface, VK_FORMAT_R8G8B8A8_UNORM,
                                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &swapchain));

  VkFence fence;
  VkFenceCreateInfo info{
      .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, .pNext = nullptr, .flags = 0};
  vkCreateFence(test_->vk_device_, &info, nullptr, &fence);

  // The swapchain itself outputs an error when it receives a fence.
  test_->allows_validation_errors_ = true;
  uint32_t image_index;
  EXPECT_EQ(VK_ERROR_DEVICE_LOST,
            test_->acquire_next_image_khr_(test_->vk_device_, swapchain, 0, VK_NULL_HANDLE, fence,
                                           &image_index));
  test_->allows_validation_errors_ = false;
  vkDestroyFence(test_->vk_device_, fence, nullptr);

  test_->destroy_swapchain_khr_(test_->vk_device_, swapchain, nullptr);
  vkDestroySurfaceKHR(test_->vk_instance_, surface, nullptr);
}

INSTANTIATE_TEST_SUITE_P(SwapchainTestSuite, SwapchainTest,
                         ::testing::Combine(::testing::Bool(), ::testing::Bool(),
                                            ::testing::Bool()),
                         NameFromParam);

class SwapchainFidlTest : public SwapchainTest {};

TEST_P(SwapchainFidlTest, PresentAndAcquireNoSemaphore) {
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);

  std::unique_ptr<FakeFlatland> flatland;
  GetFakeFlatlandInjectedToLib(&flatland, /*should_present=*/true);

  auto [view_token, viewport_token] = scenic::ViewCreationTokenPair::New();
  VkImagePipeSurfaceCreateInfoFUCHSIA create_info = {
      .sType = VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA,
      .pNext = nullptr,
      .imagePipeHandle = view_token.value.release(),
  };
  VkSurfaceKHR surface;
  EXPECT_EQ(VK_SUCCESS,
            vkCreateImagePipeSurfaceFUCHSIA(test_->vk_instance_, &create_info, nullptr, &surface));

  VkSwapchainKHR swapchain;
  ASSERT_EQ(VK_SUCCESS,
            test_->CreateSwapchainHelper(surface, VK_FORMAT_B8G8R8A8_UNORM,
                                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &swapchain));

  VkQueue queue;
  if (use_protected_memory()) {
    VkDeviceQueueInfo2 queue_info2 = {.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
                                      .pNext = nullptr,
                                      .flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,
                                      .queueFamilyIndex = 0,
                                      .queueIndex = 0};
    test_->get_device_queue2_(test_->vk_device_, &queue_info2, &queue);
  } else {
    vkGetDeviceQueue(test_->vk_device_, 0, 0, &queue);
  }

  // Supplying neither fences nor semaphores is against the vulkan spec.
  test_->allows_validation_errors_ = true;
  uint32_t image_index;
  // Acquire all initial images.
  for (uint32_t i = 0; i < 3; i++) {
    EXPECT_EQ(VK_SUCCESS,
              test_->acquire_next_image_khr_(test_->vk_device_, swapchain, 0, VK_NULL_HANDLE,
                                             VK_NULL_HANDLE, &image_index));
    EXPECT_EQ(i, image_index);
  }

  EXPECT_EQ(VK_NOT_READY,
            test_->acquire_next_image_khr_(test_->vk_device_, swapchain, 0, VK_NULL_HANDLE,
                                           VK_NULL_HANDLE, &image_index));

  ASSERT_DEATH(test_->acquire_next_image_khr_(test_->vk_device_, swapchain, UINT64_MAX,
                                              VK_NULL_HANDLE, VK_NULL_HANDLE, &image_index),
               ".*Currently all images are pending.*");
  test_->allows_validation_errors_ = false;

  uint32_t present_index;  // Initialized below.
  VkResult present_result;
  VkPresentInfoKHR present_info = {
      .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
      .pNext = nullptr,
      .waitSemaphoreCount = 0,
      .pWaitSemaphores = nullptr,
      .swapchainCount = 1,
      .pSwapchains = &swapchain,
      .pImageIndices = &present_index,
      .pResults = &present_result,
  };

  constexpr uint32_t kFrameCount = 100;
  for (uint32_t i = 0; i < kFrameCount; i++) {
    present_index = i % 3;
    auto swapchain_images = test_->GetSwapchainImages(swapchain);
    test_->TransitionLayout(swapchain_images[present_index], VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
    ASSERT_EQ(VK_SUCCESS, test_->queue_present_khr_(queue, &present_info));

    // Flatland only releases images after a subsequent Present(), so the first image won't be
    // released right away.
    if (!with_copy() && i == 0) {
      continue;
    }

    // Supplying neither fences nor semaphores is against the vulkan spec.
    test_->allows_validation_errors_ = true;
    constexpr uint64_t kTimeoutNs = std::chrono::nanoseconds(std::chrono::seconds(10)).count();
    EXPECT_EQ(VK_SUCCESS,
              test_->acquire_next_image_khr_(test_->vk_device_, swapchain, kTimeoutNs,
                                             VK_NULL_HANDLE, VK_NULL_HANDLE, &image_index));
    if (with_copy()) {
      ASSERT_EQ(present_index, image_index);
    } else {
      // The previous present image should be available.
      ASSERT_EQ(present_index, (image_index + 1) % 3);
    }

    ASSERT_EQ(VK_NOT_READY,
              test_->acquire_next_image_khr_(test_->vk_device_, swapchain, 0, VK_NULL_HANDLE,
                                             VK_NULL_HANDLE, &image_index));
    test_->allows_validation_errors_ = false;
  }

  test_->destroy_swapchain_khr_(test_->vk_device_, swapchain, nullptr);
  vkDestroySurfaceKHR(test_->vk_instance_, surface, nullptr);

  if (with_copy()) {
    EXPECT_GE(flatland->presented_count(), kFrameCount - 1);
    EXPECT_GE(flatland->acquire_fences_count(), kFrameCount - 1);
  } else {
    EXPECT_EQ(flatland->presented_count(), kFrameCount);
    EXPECT_EQ(flatland->acquire_fences_count(), kFrameCount);
  }
}

TEST_P(SwapchainFidlTest, ForceQuit) {
  std::unique_ptr<FakeFlatland> flatland;
  GetFakeFlatlandInjectedToLib(&flatland, /*should_present=*/true);

  auto [view_token, viewport_token] = scenic::ViewCreationTokenPair::New();
  VkImagePipeSurfaceCreateInfoFUCHSIA create_info = {
      .sType = VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA,
      .pNext = nullptr,
      .imagePipeHandle = view_token.value.release(),
  };
  VkSurfaceKHR surface;
  EXPECT_EQ(VK_SUCCESS,
            vkCreateImagePipeSurfaceFUCHSIA(test_->vk_instance_, &create_info, nullptr, &surface));

  VkSwapchainKHR swapchain;
  ASSERT_EQ(VK_SUCCESS,
            test_->CreateSwapchainHelper(surface, VK_FORMAT_B8G8R8A8_UNORM,
                                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &swapchain));

  VkQueue queue;
  if (use_protected_memory()) {
    VkDeviceQueueInfo2 queue_info2 = {.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
                                      .pNext = nullptr,
                                      .flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,
                                      .queueFamilyIndex = 0,
                                      .queueIndex = 0};
    test_->get_device_queue2_(test_->vk_device_, &queue_info2, &queue);
  } else {
    vkGetDeviceQueue(test_->vk_device_, 0, 0, &queue);
  }

  uint32_t image_index;
  EXPECT_EQ(VK_SUCCESS,
            test_->acquire_next_image_khr_(test_->vk_device_, swapchain, 0,
                                           MakeSingleUseSemaphore(), VK_NULL_HANDLE, &image_index));

  auto swapchain_images = test_->GetSwapchainImages(swapchain);
  test_->TransitionLayout(swapchain_images[image_index], VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);

  uint32_t present_index = image_index;
  VkResult present_result;
  VkPresentInfoKHR present_info = {
      .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
      .pNext = nullptr,
      .waitSemaphoreCount = 0,
      .pWaitSemaphores = nullptr,
      .swapchainCount = 1,
      .pSwapchains = &swapchain,
      .pImageIndices = &present_index,
      .pResults = &present_result,
  };

  ASSERT_EQ(VK_SUCCESS, test_->queue_present_khr_(queue, &present_info));
  flatland.reset();

  test_->destroy_swapchain_khr_(test_->vk_device_, swapchain, nullptr);
  vkDestroySurfaceKHR(test_->vk_instance_, surface, nullptr);
}

TEST_P(SwapchainFidlTest, DeviceLostAvoidSemaphoreHang) {
  // TODO(58325): The emulator will block of a command queue with a pending fence is submitted. So
  // this test, which depends on a delayed GPU execution, will deadlock.
  if (GetVkPhysicalDeviceType(test_->vk_physical_device_) == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) {
    GTEST_SKIP();
  }
  // Surface lost isn't seen by the copy swapchain
  if (with_copy())
    GTEST_SKIP();

  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);

  std::unique_ptr<FakeFlatland> flatland;
  GetFakeFlatlandInjectedToLib(&flatland, /*should_present=*/false);

  auto [view_token, viewport_token] = scenic::ViewCreationTokenPair::New();
  VkImagePipeSurfaceCreateInfoFUCHSIA create_info = {
      .sType = VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA,
      .pNext = nullptr,
      .imagePipeHandle = view_token.value.release(),
  };
  VkSurfaceKHR surface;
  EXPECT_EQ(VK_SUCCESS,
            vkCreateImagePipeSurfaceFUCHSIA(test_->vk_instance_, &create_info, nullptr, &surface));

  VkSwapchainKHR swapchain;
  ASSERT_EQ(VK_SUCCESS,
            test_->CreateSwapchainHelper(surface, VK_FORMAT_B8G8R8A8_UNORM,
                                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &swapchain));

  VkQueue queue;
  if (use_protected_memory()) {
    VkDeviceQueueInfo2 queue_info2 = {.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
                                      .pNext = nullptr,
                                      .flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,
                                      .queueFamilyIndex = 0,
                                      .queueIndex = 0};
    test_->get_device_queue2_(test_->vk_device_, &queue_info2, &queue);
  } else {
    vkGetDeviceQueue(test_->vk_device_, 0, 0, &queue);
  }

  uint32_t image_index;
  // Acquire all initial images.
  for (uint32_t i = 0; i < 3; i++) {
    EXPECT_EQ(VK_SUCCESS, test_->acquire_next_image_khr_(test_->vk_device_, swapchain, 0,
                                                         MakeSingleUseSemaphore(), VK_NULL_HANDLE,
                                                         &image_index));
    EXPECT_EQ(i, image_index);
  }

  uint32_t present_index;  // Initialized below.
  VkResult present_result;
  VkPresentInfoKHR present_info = {
      .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
      .pNext = nullptr,
      .waitSemaphoreCount = 0,
      .pWaitSemaphores = nullptr,
      .swapchainCount = 1,
      .pSwapchains = &swapchain,
      .pImageIndices = &present_index,
      .pResults = &present_result,
  };

  present_index = 0;
  auto swapchain_images = test_->GetSwapchainImages(swapchain);
  test_->TransitionLayout(swapchain_images[present_index], VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
  ASSERT_EQ(VK_SUCCESS, test_->queue_present_khr_(queue, &present_info));
  present_index = 1;
  test_->TransitionLayout(swapchain_images[present_index], VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
  ASSERT_EQ(VK_SUCCESS, test_->queue_present_khr_(queue, &present_info));

  VkSemaphoreCreateInfo semaphore_create_info{.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
  VkSemaphore semaphore;
  ASSERT_EQ(VK_SUCCESS,
            vkCreateSemaphore(test_->vk_device_, &semaphore_create_info, nullptr, &semaphore));

  ASSERT_EQ(VK_SUCCESS, test_->acquire_next_image_khr_(test_->vk_device_, swapchain, UINT64_MAX,
                                                       semaphore, VK_NULL_HANDLE, &image_index));

  VkPipelineStageFlags wait_flag = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
  VkSubmitInfo info{.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
                    .pNext = nullptr,
                    .waitSemaphoreCount = 1,
                    .pWaitSemaphores = &semaphore,
                    .pWaitDstStageMask = &wait_flag};
  ASSERT_EQ(VK_SUCCESS, vkQueueSubmit(queue, 1, &info, VK_NULL_HANDLE));

  auto future = std::async(std::launch::async, [flatland = std::move(flatland)]() mutable {
    // Wait enough time for the DeviceWaitIdle to start waiting on the semaphore, but not enough
    // time to get a lost device.
    zx::nanosleep(zx::deadline_after(zx::sec(1)));
    flatland.reset();
  });
  auto acquire_future = std::async(std::launch::async, [test = test_.get(), &swapchain]() mutable {
    uint32_t image_index;
    // No semaphore or fence, so this should wait on the CPU. Supplying neither fences nor
    // semaphores is against the vulkan spec.
    test->allows_validation_errors_ = true;
    EXPECT_EQ(VK_ERROR_SURFACE_LOST_KHR,
              test->acquire_next_image_khr_(test->vk_device_, swapchain, UINT64_MAX, VK_NULL_HANDLE,
                                            VK_NULL_HANDLE, &image_index));
    test->allows_validation_errors_ = false;
  });
  vkDeviceWaitIdle(test_->vk_device_);
  // Wait before the queue_present_khr to externally synchronize access to |swapchain|.
  acquire_future.wait();

  present_index = 2;
  test_->TransitionLayout(swapchain_images[present_index], VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
  EXPECT_EQ(VK_SUCCESS, test_->queue_present_khr_(queue, &present_info));
  EXPECT_EQ(VK_ERROR_SURFACE_LOST_KHR, present_result);

  vkDestroySemaphore(test_->vk_device_, semaphore, nullptr);

  test_->destroy_swapchain_khr_(test_->vk_device_, swapchain, nullptr);
  vkDestroySurfaceKHR(test_->vk_instance_, surface, nullptr);
}

TEST_P(SwapchainFidlTest, AcquireZeroTimeout) {
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);

  std::unique_ptr<FakeFlatland> flatland;
  GetFakeFlatlandInjectedToLib(&flatland, /*should_present=*/false);

  auto [view_token, viewport_token] = scenic::ViewCreationTokenPair::New();
  VkImagePipeSurfaceCreateInfoFUCHSIA create_info = {
      .sType = VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA,
      .pNext = nullptr,
      .imagePipeHandle = view_token.value.release(),
  };

  VkSurfaceKHR surface;
  EXPECT_EQ(VK_SUCCESS,
            vkCreateImagePipeSurfaceFUCHSIA(test_->vk_instance_, &create_info, nullptr, &surface));

  VkSwapchainKHR swapchain;
  ASSERT_EQ(VK_SUCCESS,
            test_->CreateSwapchainHelper(surface, VK_FORMAT_B8G8R8A8_UNORM,
                                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &swapchain));

  VkQueue queue;
  if (use_protected_memory()) {
    VkDeviceQueueInfo2 queue_info2 = {.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
                                      .pNext = nullptr,
                                      .flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,
                                      .queueFamilyIndex = 0,
                                      .queueIndex = 0};
    test_->get_device_queue2_(test_->vk_device_, &queue_info2, &queue);
  } else {
    vkGetDeviceQueue(test_->vk_device_, 0, 0, &queue);
  }
  uint32_t image_index;
  // Acquire all initial images.
  for (uint32_t i = 0; i < 3; i++) {
    EXPECT_EQ(VK_SUCCESS, test_->acquire_next_image_khr_(test_->vk_device_, swapchain, 0,
                                                         MakeSingleUseSemaphore(), VK_NULL_HANDLE,
                                                         &image_index));
    EXPECT_EQ(i, image_index);
  }

  // Timeout of zero with no pending presents
  EXPECT_EQ(VK_NOT_READY,
            test_->acquire_next_image_khr_(test_->vk_device_, swapchain, 0,
                                           MakeSingleUseSemaphore(), VK_NULL_HANDLE, &image_index));

  uint32_t present_index = 0;
  auto swapchain_images = test_->GetSwapchainImages(swapchain);
  test_->TransitionLayout(swapchain_images[present_index], VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
  VkResult present_result;
  VkPresentInfoKHR present_info = {
      .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
      .pNext = nullptr,
      .waitSemaphoreCount = 0,
      .pWaitSemaphores = nullptr,
      .swapchainCount = 1,
      .pSwapchains = &swapchain,
      .pImageIndices = &present_index,
      .pResults = &present_result,
  };

  ASSERT_EQ(VK_SUCCESS, test_->queue_present_khr_(queue, &present_info));

  {
    // It's a validation error to not specify a fence or semaphore.
    test_->allows_validation_errors_ = true;
    // Timeout of zero with pending presents
    VkResult result = test_->acquire_next_image_khr_(test_->vk_device_, swapchain, 0,
                                                     VK_NULL_HANDLE, VK_NULL_HANDLE, &image_index);
    if (with_copy()) {
      // The copy may have finished and signaled the release fence.
      EXPECT_TRUE((result == VK_SUCCESS) || (result == VK_NOT_READY));
    } else {
      EXPECT_EQ(result, VK_NOT_READY);
    }
    test_->allows_validation_errors_ = false;
  }

  // Close the remote end because we've configured it to not-present, and the swapchain
  // teardown hangs otherwise.
  flatland.reset();

  test_->destroy_swapchain_khr_(test_->vk_device_, swapchain, nullptr);
  vkDestroySurfaceKHR(test_->vk_instance_, surface, nullptr);
}

INSTANTIATE_TEST_SUITE_P(SwapchainFidlTestSuite, SwapchainFidlTest,
                         ::testing::Combine(::testing::Bool(), ::testing::Bool(),
                                            ::testing::Bool()),
                         NameFromParam);
