/*
 * Copyright (C) 2020 ARM Limited. All rights reserved.
 *
 * Copyright 2016 The Android Open Source Project
 *
 * 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 <inttypes.h>
#include <sync/sync.h>
#include "RegisteredHandlePool.h"
#include "Mapper.h"
#include "BufferDescriptor.h"
#include "mali_gralloc_log.h"
#include "core/mali_gralloc_bufferallocation.h"
#include "core/mali_gralloc_bufferdescriptor.h"
#include "core/mali_gralloc_bufferaccess.h"
#include "core/mali_gralloc_reference.h"
#include "core/format_info.h"
#include "allocator/mali_gralloc_ion.h"
#include "mali_gralloc_buffer.h"
#include "mali_gralloc_log.h"

#include "MapperMetadata.h"
#include "SharedMetadata.h"

/* GraphicBufferMapper is expected to be valid (and leaked) during process
 * termination. IMapper, and in turn, gRegisteredHandles must be valid as
 * well. Create the registered handle pool on the heap, and let
 * it leak for simplicity.
 *
 * However, there is no way to make sure gralloc0/gralloc1 are valid. Any use
 * of static/global object in gralloc0/gralloc1 that may have been destructed
 * is potentially broken.
 */
RegisteredHandlePool* gRegisteredHandles = new RegisteredHandlePool;

namespace arm {
namespace mapper {
namespace common {

/*
 * Translates the register buffer API into existing gralloc implementation
 *
 * @param bufferHandle [in] Private handle for the buffer to be imported
 *
 * @return Error::BAD_BUFFER for an invalid buffer
 *         Error::NO_RESOURCES when unable to import the given buffer
 *         Error::NONE on successful import
 */
static Error registerBuffer(buffer_handle_t bufferHandle)
{
	if (private_handle_t::validate(bufferHandle) < 0)
	{
		MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
		return Error::BAD_BUFFER;
	}

	if (mali_gralloc_reference_retain(bufferHandle) < 0)
	{
		return Error::NO_RESOURCES;
	}

	return Error::NONE;
}

/*
 * Translates the unregister buffer API into existing gralloc implementation
 *
 * @param bufferHandle [in] Private handle for the buffer to be released
 *
 * @return Error::BAD_BUFFER for an invalid buffer / buffers which can't be released
 *         Error::NONE on successful release of the buffer
 */
static Error unregisterBuffer(buffer_handle_t bufferHandle)
{
	if (private_handle_t::validate(bufferHandle) < 0)
	{
		MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
		return Error::BAD_BUFFER;
	}

	const int status = mali_gralloc_reference_release(bufferHandle);
	if (status != 0)
	{
		MALI_GRALLOC_LOGE("Unable to release buffer:%p", bufferHandle);
		return Error::BAD_BUFFER;
	}

	return Error::NONE;
}

/*
 * Retrieves the file descriptor referring to a sync fence object
 *
 * @param fenceHandle [in]  HIDL fence handle
 * @param outFenceFd  [out] Fence file descriptor. '-1' indicates no fence
 *
 * @return false, for an invalid HIDL fence handle
 *         true, otherwise
 */
static bool getFenceFd(const hidl_handle& fenceHandle, int* outFenceFd)
{
	auto const handle = fenceHandle.getNativeHandle();
	if (handle && handle->numFds > 1)
	{
		MALI_GRALLOC_LOGE("Invalid fence handle with %d fds", handle->numFds);
		return false;
	}

	*outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
	return true;
}

/*
 * Populates the HIDL fence handle for the given fence object
 *
 * @param fenceFd       [in] Fence file descriptor
 * @param handleStorage [in] HIDL handle storage for fence
 *
 * @return HIDL fence handle
 */
static hidl_handle getFenceHandle(int fenceFd, char* handleStorage)
{
	native_handle_t* handle = nullptr;
	if (fenceFd >= 0)
	{
		handle = native_handle_init(handleStorage, 1, 0);
		handle->data[0] = fenceFd;
	}

	return hidl_handle(handle);
}

/*
 * Locks the given buffer for the specified CPU usage.
 *
 * @param bufferHandle [in]  Buffer to lock.
 * @param cpuUsage     [in]  Specifies one or more CPU usage flags to request
 * @param accessRegion [in]  Portion of the buffer that the client intends to access.
 * @param fenceFd      [in]  Fence file descriptor
 * @param outData      [out] CPU accessible buffer address
 *
 * @return Error::BAD_BUFFER for an invalid buffer
 *         Error::NO_RESOURCES when unable to duplicate fence
 *         Error::BAD_VALUE when locking fails
 *         Error::NONE on successful buffer lock
 */
static Error lockBuffer(buffer_handle_t bufferHandle,
                        uint64_t cpuUsage,
                        const IMapper::Rect& accessRegion, int fenceFd,
                        void** outData)
{
	/* dup fenceFd as it is going to be owned by gralloc. Note that it is
	 * gralloc's responsibility to close it, even on locking errors.
	 */
	if (fenceFd >= 0)
	{
		fenceFd = dup(fenceFd);
		if (fenceFd < 0)
		{
			MALI_GRALLOC_LOGE("Error encountered while duplicating fence file descriptor");
			return Error::NO_RESOURCES;
		}
	}

	if (private_handle_t::validate(bufferHandle) < 0)
	{
		if (fenceFd >= 0)
		{
			close(fenceFd);
		}
		MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
		return Error::BAD_BUFFER;
	}

	if (mali_gralloc_reference_validate(bufferHandle) < 0)
	{
		if (fenceFd >= 0)
		{
			close(fenceFd);
		}
		MALI_GRALLOC_LOGE("Buffer: %p is not imported", bufferHandle);
		return Error::BAD_VALUE;
	}

	auto private_handle = private_handle_t::dynamicCast(bufferHandle);
	if (private_handle->cpu_write != 0 && (cpuUsage & BufferUsage::CPU_WRITE_MASK))
	{
		if (fenceFd >= 0)
		{
			close(fenceFd);
		}
#if 0
		MALI_GRALLOC_LOGW("Attempt to call lock*() for writing on an already locked buffer (%p)", bufferHandle);
#endif

		/* TODO: handle simulatneous locks differently. May be keep a global lock count per buffer? */
	}
	else if (fenceFd >= 0)
	{
		sync_wait(fenceFd, -1);
		close(fenceFd);
	}

	void* data = nullptr;
	if (mali_gralloc_lock(bufferHandle, cpuUsage, accessRegion.left, accessRegion.top, accessRegion.width,
	                      accessRegion.height, &data) < 0)
	{
		return Error::BAD_VALUE;
	}

	*outData = data;

	return Error::NONE;
}

/*
 * Unlocks a buffer to indicate all CPU accesses to the buffer have completed
 *
 * @param bufferHandle [in]  Buffer to lock.
 * @param outFenceFd   [out] Fence file descriptor
 *
 * @return Error::BAD_BUFFER for an invalid buffer
 *         Error::BAD_VALUE when unlocking failed
 *         Error::NONE on successful buffer unlock
 */
static Error unlockBuffer(buffer_handle_t bufferHandle,
                                  int* outFenceFd)
{
	if (private_handle_t::validate(bufferHandle) < 0)
	{
		MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
		return Error::BAD_BUFFER;
	}

	auto private_handle = private_handle_t::dynamicCast(bufferHandle);

	const int result = mali_gralloc_unlock(bufferHandle);
	if (result)
	{
		MALI_GRALLOC_LOGE("Unlocking failed with error: %d", result);
		return Error::BAD_VALUE;
	}

	*outFenceFd = -1;

	return Error::NONE;
}

void importBuffer(const hidl_handle& rawHandle, IMapper::importBuffer_cb hidl_cb)
{
	if (!rawHandle.getNativeHandle())
	{
		MALI_GRALLOC_LOGE("Invalid buffer handle to import");
		hidl_cb(Error::BAD_BUFFER, nullptr);
		return;
	}

	native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
	if (!bufferHandle)
	{
		MALI_GRALLOC_LOGE("Failed to clone buffer handle");
		hidl_cb(Error::NO_RESOURCES, nullptr);
		return;
	}

	const Error error = registerBuffer(bufferHandle);
	if (error != Error::NONE)
	{
		native_handle_close(bufferHandle);
		native_handle_delete(bufferHandle);

		hidl_cb(error, nullptr);
		return;
	}

	auto *private_handle = static_cast<private_handle_t *>(bufferHandle);

	if (gRegisteredHandles->add(bufferHandle) == false)
	{
		/* The newly cloned handle is already registered. This can only happen
		 * when a handle previously registered was native_handle_delete'd instead
		 * of freeBuffer'd.
		 */
		MALI_GRALLOC_LOGE("Handle %p has already been imported; potential fd leaking",
		       bufferHandle);
		unregisterBuffer(bufferHandle);
		native_handle_close(bufferHandle);
		native_handle_delete(bufferHandle);

		hidl_cb(Error::NO_RESOURCES, nullptr);
		return;
	}

	hidl_cb(Error::NONE, bufferHandle);
}

Error freeBuffer(void* buffer)
{
	native_handle_t * const bufferHandle = gRegisteredHandles->remove(buffer);
	if (!bufferHandle)
	{
		MALI_GRALLOC_LOGE("Invalid buffer handle %p to freeBuffer", buffer);
		return Error::BAD_BUFFER;
	}

	const Error status = unregisterBuffer(bufferHandle);
	if (status != Error::NONE)
	{
		return status;
	}

	native_handle_close(bufferHandle);
	native_handle_delete(bufferHandle);

	return Error::NONE;
}

void lock(void* buffer, uint64_t cpuUsage, const IMapper::Rect& accessRegion,
          const hidl_handle& acquireFence, IMapper::lock_cb hidl_cb)
{
	buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
	if (!bufferHandle || private_handle_t::validate(bufferHandle) < 0)
	{
		MALI_GRALLOC_LOGE("Buffer to lock: %p is not valid", buffer);
		hidl_cb(Error::BAD_BUFFER, nullptr);
		return;
	}

	int fenceFd;
	if (!getFenceFd(acquireFence, &fenceFd))
	{
		hidl_cb(Error::BAD_VALUE, nullptr);
		return;
	}

	void* data = nullptr;
	const Error error = lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &data);

	hidl_cb(error, data);
}

void unlock(void* buffer, IMapper::unlock_cb hidl_cb)
{
	buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
	if (!bufferHandle)
	{
		MALI_GRALLOC_LOGE("Buffer to unlock: %p has not been registered with Gralloc", buffer);
		hidl_cb(Error::BAD_BUFFER, nullptr);
		return;
	}

	int fenceFd;
	const Error error = unlockBuffer(bufferHandle, &fenceFd);
	if (error == Error::NONE)
	{
		NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
		hidl_cb(error, getFenceHandle(fenceFd, fenceStorage));

		if (fenceFd >= 0)
		{
			close(fenceFd);
		}
	}
	else
	{
		hidl_cb(error, nullptr);
	}
}

Error validateBufferSize(void* buffer,
                         const IMapper::BufferDescriptorInfo& descriptorInfo,
                         uint32_t in_stride)
{
	/* The buffer must have been allocated by Gralloc */
	buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
	if (!bufferHandle)
	{
		MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
		return Error::BAD_BUFFER;
	}

	if (private_handle_t::validate(bufferHandle) < 0)
	{
		MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
		return Error::BAD_BUFFER;
	}

	buffer_descriptor_t grallocDescriptor;
	grallocDescriptor.width = descriptorInfo.width;
	grallocDescriptor.height = descriptorInfo.height;
	grallocDescriptor.layer_count = descriptorInfo.layerCount;
	grallocDescriptor.hal_format = static_cast<uint64_t>(descriptorInfo.format);
	grallocDescriptor.producer_usage = static_cast<uint64_t>(descriptorInfo.usage);
	grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage;
	grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;

	/* Derive the buffer size for the given descriptor */
	const int result = mali_gralloc_derive_format_and_size(&grallocDescriptor);
	if (result)
	{
		MALI_GRALLOC_LOGV("Unable to derive format and size for the given descriptor information. error: %d", result);
		return Error::BAD_VALUE;
	}

	/* Validate the buffer parameters against descriptor info */
	private_handle_t *gralloc_buffer = (private_handle_t *)bufferHandle;

	/* The buffer size must be greater than (or equal to) what would have been allocated with descriptor */
	for (int i = 0; i < gralloc_buffer->fd_count; i++)
	{
		if (gralloc_buffer->alloc_sizes[i] < grallocDescriptor.alloc_sizes[i])
		{
			MALI_GRALLOC_LOGW("Buf size mismatch. fd_idx(%d) Buffer size = %" PRIu64 ", Descriptor (derived) size = %" PRIu64,
			       i, gralloc_buffer->alloc_sizes[i], grallocDescriptor.alloc_sizes[i]);
			return Error::BAD_VALUE;
		}
	}

	if (in_stride != 0 && (uint32_t)gralloc_buffer->stride != in_stride)
	{
		MALI_GRALLOC_LOGE("Stride mismatch. Expected stride = %d, Buffer stride = %d",
		                       in_stride, gralloc_buffer->stride);
		return Error::BAD_VALUE;
	}

	if (gralloc_buffer->alloc_format != grallocDescriptor.alloc_format)
	{
		MALI_GRALLOC_LOGE("Buffer alloc format: (%s, 0x%" PRIx64") does not match descriptor (derived) alloc format: (%s 0x%"
			PRIx64 ")", format_name(gralloc_buffer->alloc_format), gralloc_buffer->alloc_format,
			format_name(grallocDescriptor.alloc_format), grallocDescriptor.alloc_format);
		return Error::BAD_VALUE;
	}

	const int format_idx = get_format_index(gralloc_buffer->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
	if (format_idx == -1)
	{
		MALI_GRALLOC_LOGE("Invalid format to validate buffer descriptor");
		return Error::BAD_VALUE;
	}
	else
	{
		for (int i = 0; i < formats[format_idx].npln; i++)
		{
			if (gralloc_buffer->plane_info[i].byte_stride != grallocDescriptor.plane_info[i].byte_stride)
			{
				MALI_GRALLOC_LOGE("Buffer byte stride 0x%x mismatch with desc byte stride 0x%x in plane %d ",
				      gralloc_buffer->plane_info[i].byte_stride, grallocDescriptor.plane_info[i].byte_stride, i);
				return Error::BAD_VALUE;
			}

			if (gralloc_buffer->plane_info[i].alloc_width != grallocDescriptor.plane_info[i].alloc_width)
			{
				MALI_GRALLOC_LOGE("Buffer alloc width 0x%x mismatch with desc alloc width 0x%x in plane %d ",
				      gralloc_buffer->plane_info[i].alloc_width, grallocDescriptor.plane_info[i].alloc_width, i);
				return Error::BAD_VALUE;
			}

			if (gralloc_buffer->plane_info[i].alloc_height != grallocDescriptor.plane_info[i].alloc_height)
			{
				MALI_GRALLOC_LOGE("Buffer alloc height 0x%x mismatch with desc alloc height 0x%x in plane %d ",
				      gralloc_buffer->plane_info[i].alloc_height, grallocDescriptor.plane_info[i].alloc_height, i);
				return Error::BAD_VALUE;
			}
		}
	}

	if ((uint32_t)gralloc_buffer->width != grallocDescriptor.width)
	{
		MALI_GRALLOC_LOGE("Width mismatch. Buffer width = %u, Descriptor width = %u",
		      gralloc_buffer->width, grallocDescriptor.width);
		return Error::BAD_VALUE;
	}

	if ((uint32_t)gralloc_buffer->height != grallocDescriptor.height)
	{
		MALI_GRALLOC_LOGE("Height mismatch. Buffer height = %u, Descriptor height = %u",
		      gralloc_buffer->height, grallocDescriptor.height);
		return Error::BAD_VALUE;
	}

	if (gralloc_buffer->layer_count != grallocDescriptor.layer_count)
	{
		MALI_GRALLOC_LOGE("Layer Count mismatch. Buffer layer_count = %u, Descriptor layer_count width = %u",
		      gralloc_buffer->layer_count, grallocDescriptor.layer_count);
		return Error::BAD_VALUE;
	}

	return Error::NONE;
}

void getTransportSize(void* buffer, IMapper::getTransportSize_cb hidl_cb)
{
	/* The buffer must have been allocated by Gralloc */
	buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
	if (!bufferHandle)
	{
		MALI_GRALLOC_LOGE("Buffer %p is not registered with Gralloc", bufferHandle);
		hidl_cb(Error::BAD_BUFFER, -1, -1);
		return;
	}

	if (private_handle_t::validate(bufferHandle) < 0)
	{
		MALI_GRALLOC_LOGE("Buffer %p is corrupted", buffer);
		hidl_cb(Error::BAD_BUFFER, -1, -1);
		return;
	}
	hidl_cb(Error::NONE, bufferHandle->numFds, bufferHandle->numInts);
}

void isSupported(const IMapper::BufferDescriptorInfo& description, IMapper::isSupported_cb hidl_cb)
{
	buffer_descriptor_t grallocDescriptor;
	grallocDescriptor.width = description.width;
	grallocDescriptor.height = description.height;
	grallocDescriptor.layer_count = description.layerCount;
	grallocDescriptor.hal_format = static_cast<uint64_t>(description.format);
	grallocDescriptor.producer_usage = static_cast<uint64_t>(description.usage);
	grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage;
	grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;

	/* Check if it is possible to allocate a buffer for the given description */
	const int result = mali_gralloc_derive_format_and_size(&grallocDescriptor);
	if (result != 0)
	{
		MALI_GRALLOC_LOGV("Allocation for the given description will not succeed. error: %d", result);
		hidl_cb(Error::NONE, false);
	}
	else
	{
		hidl_cb(Error::NONE, true);
	}
}

void flushLockedBuffer(void *buffer, IMapper::flushLockedBuffer_cb hidl_cb)
{
	buffer_handle_t handle = gRegisteredHandles->get(buffer);
	if (private_handle_t::validate(handle) < 0)
	{
		MALI_GRALLOC_LOGE("Bandle: %p is corrupted", handle);
		hidl_cb(Error::BAD_BUFFER, hidl_handle{});
		return;
	}

	auto private_handle = static_cast<const private_handle_t *>(handle);
	if (!private_handle->cpu_write && !private_handle->cpu_read)
	{
		MALI_GRALLOC_LOGE("Attempt to call flushLockedBuffer() on an unlocked buffer (%p)", handle);
		hidl_cb(Error::BAD_BUFFER, hidl_handle{});
		return;
	}

	mali_gralloc_ion_sync_end(private_handle, false, true);
	hidl_cb(Error::NONE, hidl_handle{});
}

Error rereadLockedBuffer(void *buffer)
{
	buffer_handle_t handle = gRegisteredHandles->get(buffer);
	if (private_handle_t::validate(handle) < 0)
	{
		MALI_GRALLOC_LOGE("Buffer: %p is corrupted", handle);
		return Error::BAD_BUFFER;
	}

	auto private_handle = static_cast<const private_handle_t *>(handle);
	if (!private_handle->cpu_write && !private_handle->cpu_read)
	{
		MALI_GRALLOC_LOGE("Attempt to call rereadLockedBuffer() on an unlocked buffer (%p)", handle);
		return Error::BAD_BUFFER;
	}

	mali_gralloc_ion_sync_start(private_handle, true, false);
	return Error::NONE;
}

void get(void *buffer, const IMapper::MetadataType &metadataType, IMapper::get_cb hidl_cb)
{
	/* The buffer must have been allocated by Gralloc */
	const private_handle_t *handle = static_cast<const private_handle_t *>(gRegisteredHandles->get(buffer));
	if (handle == nullptr)
	{
		MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
		hidl_cb(Error::BAD_BUFFER, hidl_vec<uint8_t>());
		return;
	}

	if (mali_gralloc_reference_validate((buffer_handle_t)handle) < 0)
	{
		MALI_GRALLOC_LOGE("Buffer: %p is not imported", handle);
		hidl_cb(Error::BAD_VALUE, hidl_vec<uint8_t>());
		return;
	}

	get_metadata(handle, metadataType, hidl_cb);
}

Error set(void *buffer, const IMapper::MetadataType &metadataType, const hidl_vec<uint8_t> &metadata)
{
	/* The buffer must have been allocated by Gralloc */
	const private_handle_t *handle = static_cast<const private_handle_t *>(gRegisteredHandles->get(buffer));
	if (handle == nullptr)
	{
		MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
		return Error::BAD_BUFFER;
	}

	if (mali_gralloc_reference_validate((buffer_handle_t)handle) < 0)
	{
		MALI_GRALLOC_LOGE("Buffer: %p is not imported", handle);
		return Error::BAD_VALUE;
	}

	return set_metadata(handle, metadataType, metadata);
}

void listSupportedMetadataTypes(IMapper::listSupportedMetadataTypes_cb hidl_cb)
{
	/* Returns a vector of {metadata type, description, isGettable, isSettable}
	*  Only non-standardMetadataTypes require a description.
	*/
	hidl_vec<IMapper::MetadataTypeDescription> descriptions = {
		{ android::gralloc4::MetadataType_BufferId, "", true, false },
		{ android::gralloc4::MetadataType_Name, "", true, false },
		{ android::gralloc4::MetadataType_Width, "", true, false },
		{ android::gralloc4::MetadataType_Height, "", true, false },
		{ android::gralloc4::MetadataType_LayerCount, "", true, false },
		{ android::gralloc4::MetadataType_PixelFormatRequested, "", true, false },
		{ android::gralloc4::MetadataType_PixelFormatFourCC, "", true, false },
		{ android::gralloc4::MetadataType_PixelFormatModifier, "", true, false },
		{ android::gralloc4::MetadataType_Usage, "", true, false },
		{ android::gralloc4::MetadataType_AllocationSize, "", true, false },
		{ android::gralloc4::MetadataType_ProtectedContent, "", true, false },
		{ android::gralloc4::MetadataType_Compression, "", true, false },
		{ android::gralloc4::MetadataType_Interlaced, "", true, false },
		{ android::gralloc4::MetadataType_ChromaSiting, "", true, false },
		{ android::gralloc4::MetadataType_PlaneLayouts, "", true, false },
		{ android::gralloc4::MetadataType_Dataspace, "", true, true },
		{ android::gralloc4::MetadataType_BlendMode, "", true, true },
		{ android::gralloc4::MetadataType_Smpte2086, "", true, true },
		{ android::gralloc4::MetadataType_Cta861_3, "", true, true },
		{ android::gralloc4::MetadataType_Smpte2094_40, "", true, true },
		{ android::gralloc4::MetadataType_Crop, "", true, true },
		/* Arm vendor metadata */
		{ ArmMetadataType_PLANE_FDS,
			"Vector of file descriptors of each plane", true, false },
	};
	hidl_cb(Error::NONE, descriptions);
	return;
}


static hidl_vec<IMapper::MetadataDump> dumpBufferHelper(const private_handle_t* handle)
{
	hidl_vec<IMapper::MetadataType> standardMetadataTypes = {
		android::gralloc4::MetadataType_BufferId,
		android::gralloc4::MetadataType_Name,
		android::gralloc4::MetadataType_Width,
		android::gralloc4::MetadataType_Height,
		android::gralloc4::MetadataType_LayerCount,
		android::gralloc4::MetadataType_PixelFormatRequested,
		android::gralloc4::MetadataType_PixelFormatFourCC,
		android::gralloc4::MetadataType_PixelFormatModifier,
		android::gralloc4::MetadataType_Usage,
		android::gralloc4::MetadataType_AllocationSize,
		android::gralloc4::MetadataType_ProtectedContent,
		android::gralloc4::MetadataType_Compression,
		android::gralloc4::MetadataType_Interlaced,
		android::gralloc4::MetadataType_ChromaSiting,
		android::gralloc4::MetadataType_PlaneLayouts,
		android::gralloc4::MetadataType_Dataspace,
		android::gralloc4::MetadataType_BlendMode,
		android::gralloc4::MetadataType_Smpte2086,
		android::gralloc4::MetadataType_Cta861_3,
		android::gralloc4::MetadataType_Smpte2094_40,
		android::gralloc4::MetadataType_Crop,
	};

	std::vector<IMapper::MetadataDump> metadataDumps;
	for (const auto& metadataType: standardMetadataTypes)
	{
		get_metadata(handle, metadataType, [&metadataDumps, &metadataType](Error error, hidl_vec<uint8_t> metadata) {
			switch(error)
			{
			case Error::NONE:
				metadataDumps.push_back({metadataType, metadata});
				break;
			case Error::UNSUPPORTED:
			default:
				return;
			}
		});
	}
	return hidl_vec<IMapper::MetadataDump>(metadataDumps);
}

void dumpBuffer(void *buffer, IMapper::dumpBuffer_cb hidl_cb)
{
	IMapper::BufferDump bufferDump{};
	auto handle = static_cast<const private_handle_t *>(gRegisteredHandles->get(buffer));
	if (handle == nullptr)
	{
		MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
		hidl_cb(Error::BAD_BUFFER, bufferDump);
		return;
	}

	bufferDump.metadataDump = dumpBufferHelper(handle);
	hidl_cb(Error::NONE, bufferDump);
}

void dumpBuffers(IMapper::dumpBuffers_cb hidl_cb)
{
	std::vector<IMapper::BufferDump> bufferDumps;
	gRegisteredHandles->for_each([&bufferDumps](buffer_handle_t buffer) {
		IMapper::BufferDump bufferDump { dumpBufferHelper(static_cast<const private_handle_t *>(buffer)) };
		bufferDumps.push_back(bufferDump);
	});
	hidl_cb(Error::NONE, hidl_vec<IMapper::BufferDump>(bufferDumps));
}

void getReservedRegion(void *buffer, IMapper::getReservedRegion_cb hidl_cb)
{
	auto handle = static_cast<const private_handle_t *>(gRegisteredHandles->get(buffer));
	if (handle == nullptr)
	{
		MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
		hidl_cb(Error::BAD_BUFFER, 0, 0);
		return;
	}
	else if (handle->reserved_region_size == 0)
	{
		MALI_GRALLOC_LOGE("Buffer: %p has no reserved region", buffer);
		hidl_cb(Error::BAD_BUFFER, 0, 0);
		return;
	}

	auto metadata_addr_oe = mali_gralloc_reference_get_metadata_addr(handle);
	if (!metadata_addr_oe.has_value()) {
		hidl_cb(Error::BAD_BUFFER, 0, 0);
	}

	void *reserved_region = static_cast<std::byte *>(metadata_addr_oe.value())
	    + mapper::common::shared_metadata_size();
	hidl_cb(Error::NONE, reserved_region, handle->reserved_region_size);
}

} // namespace common
} // namespace mapper
} // namespace arm
