// 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 VkMemoryAllocateInfo *pAllocateInfo)
	{
		OpaqueFdAllocateInfo info(pAllocateInfo);
		return info.importFd || info.exportFd;
	}

	explicit OpaqueFdExternalMemory(const VkMemoryAllocateInfo *pAllocateInfo)
	    : allocateInfo(pAllocateInfo)
	{
	}

	~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;
};
