// Copyright 2019 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 "System/Debug.hpp"

#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

#ifndef __APPLE__
#	error "This file is for macOS only!"
#endif  // __APPLE__

#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12
#	include <mach/mach_time.h>
#endif  // __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12

namespace {

struct timespec GetTime()
{
	struct timespec tv;

#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12
	clock_gettime(CLOCK_REALTIME, &tv);
#else
	mach_timebase_info_data_t timebase;
	mach_timebase_info(&timebase);
	uint64_t time;
	time = mach_absolute_time();

	double convert_ratio = (double)timebase.numer / (double)timebase.denom;
	uint64_t secs = (uint64_t)((double)time * convert_ratio / 1e-9);
	uint64_t usecs = (uint64_t)((double)time * convert_ratio - secs * 1e9);
	tv.tv_sec = secs;
	tv.tv_nsec = usecs;
#endif
	return tv;
}

}  // namespace

// An implementation of OpaqueFdExternalMemory that relies on shm_open().
// Useful on OS X which do not have Linux memfd regions.
class OpaqueFdExternalMemory : public vk::DeviceMemory::ExternalBase
{
public:
	static const VkExternalMemoryHandleTypeFlagBits typeFlagBit = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;

	static bool SupportsAllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
	{
		OpaqueFdAllocateInfo info(extendedAllocationInfo);
		return info.importFd || info.exportFd;
	}

	explicit OpaqueFdExternalMemory(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
	    : allocateInfo(extendedAllocationInfo)
	{
	}

	~OpaqueFdExternalMemory()
	{
		if(shm_fd_ >= 0)
		{
			::close(shm_fd_);
			shm_fd_ = -1;
		}
	}

	VkResult allocate(size_t size, void **pBuffer) override
	{
		if(allocateInfo.importFd)
		{
			shm_fd_ = allocateInfo.fd;
			if(shm_fd_ < 0)
			{
				return VK_ERROR_INVALID_EXTERNAL_HANDLE;
			}
		}
		else
		{
			ASSERT(allocateInfo.exportFd);
			// Create shared memory region with shm_open() and a randomly-generated region name.
			static const char kPrefix[] = "/SwiftShader-";
			const size_t kPrefixSize = sizeof(kPrefix) - 1;
			const size_t kRandomSize = 8;

			char name[kPrefixSize + kRandomSize + 1u];
			memcpy(name, kPrefix, kPrefixSize);

			int fd = -1;
			for(int tries = 0; tries < 6; ++tries)
			{
				struct timespec tv = GetTime();
				uint64_t r = (uint64_t)tv.tv_sec + (uint64_t)tv.tv_nsec;
				for(size_t pos = 0; pos < kRandomSize; ++pos, r /= 8)
				{
					name[kPrefixSize + pos] = '0' + (r % 8);
				}
				name[kPrefixSize + kRandomSize] = '\0';

				fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
				if(fd >= 0)
					break;

				if(errno != EEXIST)
				{
					TRACE("shm_open() failed with: %s", strerror(errno));
					break;
				}
			}

			// Unlink the name since it's not needed anymore.
			if(fd >= 0)
			{
				if(shm_unlink(name) == -1)
				{
					TRACE("shm_unlink() failed with: %s", strerror(errno));
					close(fd);
					fd = -1;
				}
			}

			// Ensure there is enough space.
			if(fd >= 0 && size > 0)
			{
				if(::ftruncate(fd, size) < 0)
				{
					TRACE("ftruncate() failed with: %s", strerror(errno));
					close(fd);
					fd = -1;
				}
			}

			if(fd < 0)
			{
				TRACE("Could not allocate shared memory region");
				return VK_ERROR_OUT_OF_DEVICE_MEMORY;
			}

			shm_fd_ = fd;
		}

		void *addr = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED,
		                    shm_fd_, 0);

		if(addr == MAP_FAILED)
		{
			return VK_ERROR_MEMORY_MAP_FAILED;
		}
		*pBuffer = addr;
		return VK_SUCCESS;
	}

	void deallocate(void *buffer, size_t size) override
	{
		::munmap(buffer, size);
	}

	VkExternalMemoryHandleTypeFlagBits getFlagBit() const override
	{
		return typeFlagBit;
	}

	VkResult exportFd(int *pFd) const override
	{
		int fd = dup(shm_fd_);
		if(fd < 0)
		{
			return VK_ERROR_INVALID_EXTERNAL_HANDLE;
		}

		// Set the clo-on-exec flag.
		int flags = ::fcntl(fd, F_GETFD);
		::fcntl(fd, F_SETFL, flags | FD_CLOEXEC);

		*pFd = fd;
		return VK_SUCCESS;
	}

private:
	int shm_fd_ = -1;
	OpaqueFdAllocateInfo allocateInfo;
};
