// Copyright 2018 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.

#ifndef VK_SEMAPHORE_HPP_
#define VK_SEMAPHORE_HPP_

#include "VkConfig.hpp"
#include "VkObject.hpp"

#include "marl/event.h"
#include "marl/mutex.h"
#include "marl/tsa.h"

#include "System/Synchronization.hpp"

#if VK_USE_PLATFORM_FUCHSIA
#	include <zircon/types.h>
#endif

namespace vk {

class BinarySemaphore;
class TimelineSemaphore;

class Semaphore
{
public:
	Semaphore(VkSemaphoreType type);

	virtual ~Semaphore() = default;

	static inline Semaphore *Cast(VkSemaphore semaphore)
	{
		return static_cast<Semaphore *>(static_cast<void *>(semaphore));
	}

	virtual void destroy(const VkAllocationCallbacks *pAllocator)
	{
	}

	VkSemaphoreType getSemaphoreType() const;
	//static size_t ComputeRequiredAllocationSize(const VkSemaphoreCreateInfo *pCreateInfo);

protected:
	VkSemaphoreType type;
	marl::mutex mutex;
};

class BinarySemaphore : public Semaphore, public Object<BinarySemaphore, VkSemaphore>
{
public:
	BinarySemaphore(const VkSemaphoreCreateInfo *pCreateInfo, void *mem, const VkAllocationCallbacks *pAllocator);
	void destroy(const VkAllocationCallbacks *pAllocator);

	static size_t ComputeRequiredAllocationSize(const VkSemaphoreCreateInfo *pCreateInfo);

	void wait();

	void wait(const VkPipelineStageFlags &flag)
	{
		// NOTE: not sure what else to do here?
		wait();
	}

	void signal();

#if SWIFTSHADER_EXTERNAL_SEMAPHORE_OPAQUE_FD
	VkResult importFd(int fd, bool temporaryImport);
	VkResult exportFd(int *pFd);
#endif

#if VK_USE_PLATFORM_FUCHSIA
	VkResult importHandle(zx_handle_t handle, bool temporaryImport);
	VkResult exportHandle(zx_handle_t *pHandle);
#endif

	class External;

private:
	// Small technical note on how semaphores are imported/exported with Vulkan:
	//
	// - A Vulkan Semaphore objects has a "payload", corresponding to a
	//   simple atomic boolean flag.
	//
	// - A Vulkan Semaphore object can be "exported": this creates a
	//   platform-specific handle / descriptor (which can be passed to other
	//   processes), and is linked in some way to the original semaphore's
	//   payload.
	//
	// - Similarly, said handle / descriptor can be "imported" into a Vulkan
	//   Semaphore object. By default, that semaphore loses its payload, and
	//   instead uses the one referenced / shared through the descriptor.
	//
	//   Hence if semaphore A exports its payload through a descriptor that
	//   is later imported into semaphore B, then both A and B will use/share
	//   the same payload (i.e. signal flag), making cross-process
	//   synchronization possible.
	//
	// - There are also "temporary imports", where the target semaphore's
	//   payload is not lost, but is simply hidden/stashed. But the next wait()
	//   operation on the same semaphore should remove the temporary import,
	//   and restore the previous payload.
	//
	// - There are many handle / descriptor types, which are listed through
	//   the VkExternalSemaphoreHandleTypeFlagBits. A given Vulkan
	//   implementation might support onle one or several at the same time
	//   (e.g. on Linux or Android, it could support both OPAQUE_FD_BIT and
	//   SYNC_FD_BIT, while on Windows, it would be OPAQUE_WIN32_BIT +
	//   OPAQUE_WIN32_KMT_BIT + D3D12_FENCE_BIT).
	//
	// - To be able to export a semaphore, VkCreateSemaphore() must be called
	//   with a VkSemaphoreCreateInfo that lists the types of all possible
	//   platform-specific handles the semaphore could be exported to
	//   (e.g. on Linux, it is possible to specify that a semaphore might be
	//   exported as an opaque FD, or as a Linux Sync FD).
	//
	//   However, which exact type is however only determined later by the
	//   export operation itself (e.g. vkGetSemaphoreFdKHR() could be called to export
	//   either a VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT or a
	//   VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT).
	//
	//   Once a semaphore has been exported as one type, it is not possible
	//   to export the same payload with a different type (though the spec
	//   doesn't seem to be explicit about this, it's simply impossible in
	//   general).
	//
	// This leads to the following design:
	//
	//   - |internal| is a simple marl::Event that represents the semaphore's
	//     payload when it is not exported, or imported non-temporarily.
	//
	//   - |external| points to an external semaphore payload. It is created
	//     on demand if the semaphore is exported or imported non-temporarily.
	//     Note that once |external| is created, |internal| is ignored.
	//
	//   - |tempExternal| points to a linked-list of temporary external
	//     semaphore payloads. The list head corresponds to the most recent
	//     temporary import.
	//

	// Internal template to allocate a new External implementation.
	template<class EXTERNAL>
	External *allocateExternal();

	void deallocateExternal(External *ext);

	// Used internally to import an external payload.
	// |temporaryImport| is true iff the import is temporary.
	// |alloc_func| is callable that allocates a new External instance of the
	// appropriate type.
	// |import_func| is callable that takes a single parameter, which
	// corresponds to the external handle/descriptor, and returns a VkResult
	// values.
	template<typename ALLOC_FUNC, typename IMPORT_FUNC>
	VkResult importPayload(bool temporaryImport,
	                       ALLOC_FUNC alloc_func,
	                       IMPORT_FUNC import_func);

	// Used internally to export a given payload.
	// |alloc_func| is a callable that allocates a new External instance of
	// the appropriate type.
	// |export_func| is a callable that takes a pointer to an External instance,
	// and a pointer to a handle/descriptor, and returns a VkResult.
	template<typename ALLOC_FUNC, typename EXPORT_FUNC>
	VkResult exportPayload(ALLOC_FUNC alloc_func, EXPORT_FUNC export_func);

	const VkAllocationCallbacks *allocator = nullptr;
	VkExternalSemaphoreHandleTypeFlags exportableHandleTypes = (VkExternalSemaphoreHandleTypeFlags)0;
	marl::Event internal;
	External *external GUARDED_BY(mutex) = nullptr;
	External *tempExternal GUARDED_BY(mutex) = nullptr;
};

static inline Semaphore *Cast(VkSemaphore object)
{
	return Semaphore::Cast(object);
}

template<typename T>
static inline T *DynamicCast(VkSemaphore object)
{
	Semaphore *semaphore = vk::Cast(object);
	if(semaphore == nullptr)
	{
		return nullptr;
	}

	static_assert(std::is_same_v<T, BinarySemaphore> || std::is_same_v<T, TimelineSemaphore>);
	if constexpr(std::is_same_v<T, BinarySemaphore>)
	{
		if(semaphore->getSemaphoreType() != VK_SEMAPHORE_TYPE_BINARY)
		{
			return nullptr;
		}
	}
	else
	{
		if(semaphore->getSemaphoreType() != VK_SEMAPHORE_TYPE_TIMELINE)
		{
			return nullptr;
		}
	}
	return static_cast<T *>(semaphore);
}

// This struct helps parse VkSemaphoreCreateInfo. It also looks at the pNext
// structures and stores their data flatly in a single struct. The default
// values of each data member are what the absence of a pNext struct implies
// for those values.
struct SemaphoreCreateInfo
{
	bool exportSemaphore = false;
	VkExternalSemaphoreHandleTypeFlags exportHandleTypes = 0;

	VkSemaphoreType semaphoreType = VK_SEMAPHORE_TYPE_BINARY;
	uint64_t initialPayload = 0;

	SemaphoreCreateInfo(const VkSemaphoreCreateInfo *pCreateInfo);
};

}  // namespace vk

#endif  // VK_SEMAPHORE_HPP_
