// Copyright 2021 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "VulkanTester.hpp"
#include <fstream>

#if defined(_WIN32)
#	define OS_WINDOWS 1
#elif defined(__APPLE__)
#	define OS_MAC 1
#elif defined(__ANDROID__)
#	define OS_ANDROID 1
#elif defined(__linux__)
#	define OS_LINUX 1
#elif defined(__Fuchsia__)
#	define OS_FUCHSIA 1
#else
#	error Unimplemented platform
#endif

namespace {
std::vector<const char *> getDriverPaths()
{
#if OS_WINDOWS
#	if !defined(STANDALONE)
// The DLL is delay loaded (see BUILD.gn), so we can load
// the correct ones from Chrome's swiftshader subdirectory.
// HMODULE libvulkan = LoadLibraryA("swiftshader\\libvulkan.dll");
// EXPECT_NE((HMODULE)NULL, libvulkan);
// return true;
#		error TODO: !STANDALONE
#	elif defined(NDEBUG)
#		if defined(_WIN64)
	return { "./build/Release_x64/vk_swiftshader.dll",
		     "./build/Release/vk_swiftshader.dll",
		     "./vk_swiftshader.dll" };
#		else
	return { "./build/Release_Win32/vk_swiftshader.dll",
		     "./build/Release/vk_swiftshader.dll",
		     "./vk_swiftshader.dll" };
#		endif
#	else
#		if defined(_WIN64)
	return { "./build/Debug_x64/vk_swiftshader.dll",
		     "./build/Debug/vk_swiftshader.dll",
		     "./vk_swiftshader.dll" };
#		else
	return { "./build/Debug_Win32/vk_swiftshader.dll",
		     "./build/Debug/vk_swiftshader.dll",
		     "./vk_swiftshader.dll" };
#		endif
#	endif
#elif OS_MAC
	return { "./build/Darwin/libvk_swiftshader.dylib",
		     "swiftshader/libvk_swiftshader.dylib",
		     "libvk_swiftshader.dylib" };
#elif OS_LINUX
	return { "./build/Linux/libvk_swiftshader.so",
		     "swiftshader/libvk_swiftshader.so",
		     "./libvk_swiftshader.so",
		     "libvk_swiftshader.so" };
#elif OS_ANDROID || OS_FUCHSIA
	return
	{
		"libvk_swiftshader.so"
	}
#else
#	error Unimplemented platform
	return {};
#endif
}

bool fileExists(const char *path)
{
	std::ifstream f(path);
	return f.good();
}

std::unique_ptr<vk::DynamicLoader> loadDriver()
{
	for(auto &p : getDriverPaths())
	{
		if(!fileExists(p))
			continue;
		return std::make_unique<vk::DynamicLoader>(p);
	}
	return {};
}

}  // namespace

VulkanTester::~VulkanTester()
{
	device.waitIdle();
	device.destroy(nullptr);
	instance.destroy(nullptr);
}

void VulkanTester::initialize()
{
	dl = loadDriver();
	assert(dl && dl->success());

	PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = dl->getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
	VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);

	instance = vk::createInstance({}, nullptr);
	VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);

	std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
	assert(!physicalDevices.empty());
	physicalDevice = physicalDevices[0];

	const float defaultQueuePriority = 0.0f;
	vk::DeviceQueueCreateInfo queueCreateInfo;
	queueCreateInfo.queueFamilyIndex = queueFamilyIndex;
	queueCreateInfo.queueCount = 1;
	queueCreateInfo.pQueuePriorities = &defaultQueuePriority;

	vk::DeviceCreateInfo deviceCreateInfo;
	deviceCreateInfo.queueCreateInfoCount = 1;
	deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;

	device = physicalDevice.createDevice(deviceCreateInfo, nullptr);

	queue = device.getQueue(queueFamilyIndex, 0);
}
