/*
 * Copyright 2016 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <xf86drm.h>

#ifdef __ANDROID__
#include <cutils/log.h>
#include <libgen.h>
#define MINIGBM_DEBUG "vendor.minigbm.debug"
#else
#define MINIGBM_DEBUG "MINIGBM_DEBUG"
#endif

#include "drv_helpers.h"
#include "drv_priv.h"
#include "util.h"

#ifdef DRV_AMDGPU
extern const struct backend backend_amdgpu;
#endif
#ifdef DRV_I915
extern const struct backend backend_i915;
#endif
#ifdef DRV_MSM
extern const struct backend backend_msm;
#endif
#ifdef DRV_VC4
extern const struct backend backend_vc4;
#endif

// Dumb / generic drivers
extern const struct backend backend_evdi;
extern const struct backend backend_marvell;
extern const struct backend backend_mediatek;
extern const struct backend backend_meson;
extern const struct backend backend_nouveau;
extern const struct backend backend_komeda;
extern const struct backend backend_radeon;
extern const struct backend backend_rockchip;
extern const struct backend backend_sun4i_drm;
extern const struct backend backend_synaptics;
extern const struct backend backend_virtgpu;
extern const struct backend backend_udl;
extern const struct backend backend_vkms;

extern const struct backend backend_mock;

static const struct backend *drv_backend_list[] = {
#ifdef DRV_AMDGPU
	&backend_amdgpu,
#endif
#ifdef DRV_I915
	&backend_i915,
#endif
#ifdef DRV_MSM
	&backend_msm,
#endif
#ifdef DRV_VC4
	&backend_vc4,
#endif
	&backend_evdi,	    &backend_komeda,	&backend_marvell, &backend_mediatek,
	&backend_meson,	    &backend_nouveau,	&backend_radeon,  &backend_rockchip,
	&backend_sun4i_drm, &backend_synaptics, &backend_udl,	  &backend_virtgpu,
	&backend_vkms,	    &backend_mock
};

void drv_preload(bool load)
{
	unsigned int i;
	for (i = 0; i < ARRAY_SIZE(drv_backend_list); i++) {
		const struct backend *b = drv_backend_list[i];
		if (b->preload)
			b->preload(load);
	}
}

static const struct backend *drv_get_backend(int fd)
{
	drmVersionPtr drm_version;
	unsigned int i;

	drm_version = drmGetVersion(fd);

	if (!drm_version)
		return NULL;

	for (i = 0; i < ARRAY_SIZE(drv_backend_list); i++) {
		const struct backend *b = drv_backend_list[i];
		if (!strcmp(drm_version->name, b->name)) {
			drmFreeVersion(drm_version);
			return b;
		}
	}

	drmFreeVersion(drm_version);
	return NULL;
}

struct driver *drv_create(int fd)
{
	struct driver *drv;
	int ret;

	drv = (struct driver *)calloc(1, sizeof(*drv));

	if (!drv)
		return NULL;

	const char *minigbm_debug;
	minigbm_debug = drv_get_os_option(MINIGBM_DEBUG);
	drv->compression =
	    (minigbm_debug == NULL) || (strstr(minigbm_debug, "nocompression") == NULL);
	drv->log_bos = (minigbm_debug && strstr(minigbm_debug, "log_bos") != NULL);

	drv->fd = fd;
	drv->backend = drv_get_backend(fd);

	if (!drv->backend)
		goto free_driver;

	if (pthread_mutex_init(&drv->buffer_table_lock, NULL))
		goto free_driver;

	drv->buffer_table = drmHashCreate();
	if (!drv->buffer_table)
		goto free_buffer_table_lock;

	if (pthread_mutex_init(&drv->mappings_lock, NULL))
		goto free_buffer_table;

	drv->mappings = drv_array_init(sizeof(struct mapping));
	if (!drv->mappings)
		goto free_mappings_lock;

	drv->combos = drv_array_init(sizeof(struct combination));
	if (!drv->combos)
		goto free_mappings;

	if (drv->backend->init) {
		ret = drv->backend->init(drv);
		if (ret) {
			drv_array_destroy(drv->combos);
			goto free_mappings;
		}
	}

	return drv;

free_mappings:
	drv_array_destroy(drv->mappings);
free_mappings_lock:
	pthread_mutex_destroy(&drv->mappings_lock);
free_buffer_table:
	drmHashDestroy(drv->buffer_table);
free_buffer_table_lock:
	pthread_mutex_destroy(&drv->buffer_table_lock);
free_driver:
	free(drv);
	return NULL;
}

void drv_destroy(struct driver *drv)
{
	if (drv->backend->close)
		drv->backend->close(drv);

	drv_array_destroy(drv->combos);

	drv_array_destroy(drv->mappings);
	pthread_mutex_destroy(&drv->mappings_lock);

	drmHashDestroy(drv->buffer_table);
	pthread_mutex_destroy(&drv->buffer_table_lock);

	free(drv);
}

int drv_get_fd(struct driver *drv)
{
	return drv->fd;
}

const char *drv_get_name(struct driver *drv)
{
	return drv->backend->name;
}

struct combination *drv_get_combination(struct driver *drv, uint32_t format, uint64_t use_flags)
{
	struct combination *curr, *best;

	if (format == DRM_FORMAT_NONE || use_flags == BO_USE_NONE)
		return 0;

	best = NULL;
	uint32_t i;
	for (i = 0; i < drv_array_size(drv->combos); i++) {
		curr = drv_array_at_idx(drv->combos, i);
		if ((format == curr->format) && use_flags == (curr->use_flags & use_flags))
			if (!best || best->metadata.priority < curr->metadata.priority)
				best = curr;
	}

	return best;
}

struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint32_t format,
		      uint64_t use_flags, bool is_test_buffer)
{

	struct bo *bo;
	bo = (struct bo *)calloc(1, sizeof(*bo));

	if (!bo)
		return NULL;

	bo->drv = drv;
	bo->meta.width = width;
	bo->meta.height = height;
	bo->meta.format = format;
	bo->meta.use_flags = use_flags;
	bo->meta.num_planes = drv_num_planes_from_format(format);
	bo->is_test_buffer = is_test_buffer;

	if (!bo->meta.num_planes) {
		free(bo);
		errno = EINVAL;
		return NULL;
	}

	return bo;
}

static void drv_bo_mapping_destroy(struct bo *bo)
{
	struct driver *drv = bo->drv;
	uint32_t idx = 0;

	/*
	 * This function is called right before the buffer is destroyed. It will free any mappings
	 * associated with the buffer.
	 */
	pthread_mutex_lock(&drv->mappings_lock);
	for (size_t plane = 0; plane < bo->meta.num_planes; plane++) {
		while (idx < drv_array_size(drv->mappings)) {
			struct mapping *mapping =
			    (struct mapping *)drv_array_at_idx(drv->mappings, idx);
			if (mapping->vma->handle != bo->handle.u32) {
				idx++;
				continue;
			}

			if (!--mapping->vma->refcount) {
				int ret = drv->backend->bo_unmap(bo, mapping->vma);
				if (ret) {
					pthread_mutex_unlock(&drv->mappings_lock);
					assert(ret);
					drv_loge("munmap failed\n");
					return;
				}

				free(mapping->vma);
			}

			/* This shrinks and shifts the array, so don't increment idx. */
			drv_array_remove(drv->mappings, idx);
		}
	}
	pthread_mutex_unlock(&drv->mappings_lock);
}

/*
 * Acquire a reference on plane buffers of the bo.
 */
static void drv_bo_acquire(struct bo *bo)
{
	struct driver *drv = bo->drv;

	pthread_mutex_lock(&drv->buffer_table_lock);
	for (size_t plane = 0; plane < bo->meta.num_planes; plane++) {
		uintptr_t num = 0;

		if (!drmHashLookup(drv->buffer_table, bo->handle.u32, (void **)&num))
			drmHashDelete(drv->buffer_table, bo->handle.u32);

		drmHashInsert(drv->buffer_table, bo->handle.u32, (void *)(num + 1));
	}
	pthread_mutex_unlock(&drv->buffer_table_lock);
}

/*
 * Release a reference on plane buffers of the bo. Return true when the bo has lost all its
 * references. Otherwise, return false.
 */
static bool drv_bo_release(struct bo *bo)
{
	struct driver *drv = bo->drv;
	uintptr_t num;

	if (drv->backend->bo_release)
		drv->backend->bo_release(bo);

	pthread_mutex_lock(&drv->buffer_table_lock);
	for (size_t plane = 0; plane < bo->meta.num_planes; plane++) {
		if (!drmHashLookup(drv->buffer_table, bo->handle.u32, (void **)&num)) {
			drmHashDelete(drv->buffer_table, bo->handle.u32);

			if (num > 1) {
				drmHashInsert(drv->buffer_table, bo->handle.u32, (void *)(num - 1));
			}
		}
	}

	/* The same buffer can back multiple planes with different offsets. */
	for (size_t plane = 0; plane < bo->meta.num_planes; plane++) {
		if (!drmHashLookup(drv->buffer_table, bo->handle.u32, (void **)&num)) {
			/* num is positive if found in the hashmap. */
			pthread_mutex_unlock(&drv->buffer_table_lock);
			return false;
		}
	}
	pthread_mutex_unlock(&drv->buffer_table_lock);

	return true;
}

struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, uint32_t format,
			 uint64_t use_flags)
{
	int ret;
	struct bo *bo;
	bool is_test_alloc;

	is_test_alloc = use_flags & BO_USE_TEST_ALLOC;
	use_flags &= ~BO_USE_TEST_ALLOC;

	bo = drv_bo_new(drv, width, height, format, use_flags, is_test_alloc);

	if (!bo)
		return NULL;

	ret = -EINVAL;
	if (drv->backend->bo_compute_metadata) {
		ret = drv->backend->bo_compute_metadata(bo, width, height, format, use_flags, NULL,
							0);
		if (!is_test_alloc && ret == 0)
			ret = drv->backend->bo_create_from_metadata(bo);
	} else if (!is_test_alloc) {
		ret = drv->backend->bo_create(bo, width, height, format, use_flags);
	}

	if (ret) {
		errno = -ret;
		free(bo);
		return NULL;
	}

	drv_bo_acquire(bo);

	if (drv->log_bos)
		drv_bo_log_info(bo, "legacy created");

	return bo;
}

struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint32_t height,
					uint32_t format, const uint64_t *modifiers, uint32_t count)
{
	int ret;
	struct bo *bo;

	if (!drv->backend->bo_create_with_modifiers && !drv->backend->bo_compute_metadata) {
		errno = ENOENT;
		return NULL;
	}

	bo = drv_bo_new(drv, width, height, format, BO_USE_NONE, false);

	if (!bo)
		return NULL;

	ret = -EINVAL;
	if (drv->backend->bo_compute_metadata) {
		ret = drv->backend->bo_compute_metadata(bo, width, height, format, BO_USE_NONE,
							modifiers, count);
		if (ret == 0)
			ret = drv->backend->bo_create_from_metadata(bo);
	} else {
		ret = drv->backend->bo_create_with_modifiers(bo, width, height, format, modifiers,
							     count);
	}

	if (ret) {
		free(bo);
		return NULL;
	}

	drv_bo_acquire(bo);

	if (drv->log_bos)
		drv_bo_log_info(bo, "created");

	return bo;
}

void drv_bo_destroy(struct bo *bo)
{
	if (!bo->is_test_buffer && drv_bo_release(bo)) {
		drv_bo_mapping_destroy(bo);
		bo->drv->backend->bo_destroy(bo);
	}

	free(bo);
}

struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data)
{
	int ret;
	size_t plane;
	struct bo *bo;
	off_t seek_end;

	bo = drv_bo_new(drv, data->width, data->height, data->format, data->use_flags, false);

	if (!bo)
		return NULL;

	ret = drv->backend->bo_import(bo, data);
	if (ret) {
		free(bo);
		return NULL;
	}

	drv_bo_acquire(bo);

	bo->meta.format_modifier = data->format_modifier;
	for (plane = 0; plane < bo->meta.num_planes; plane++) {
		bo->meta.strides[plane] = data->strides[plane];
		bo->meta.offsets[plane] = data->offsets[plane];

		seek_end = lseek(data->fds[plane], 0, SEEK_END);
		if (seek_end == (off_t)(-1)) {
			drv_loge("lseek() failed with %s\n", strerror(errno));
			goto destroy_bo;
		}

		lseek(data->fds[plane], 0, SEEK_SET);
		if (plane == bo->meta.num_planes - 1 || data->offsets[plane + 1] == 0)
			bo->meta.sizes[plane] = seek_end - data->offsets[plane];
		else
			bo->meta.sizes[plane] = data->offsets[plane + 1] - data->offsets[plane];

		if ((int64_t)bo->meta.offsets[plane] + bo->meta.sizes[plane] > seek_end) {
			drv_loge("buffer size is too large.\n");
			goto destroy_bo;
		}

		bo->meta.total_size += bo->meta.sizes[plane];
	}

	if (drv->log_bos)
		drv_bo_log_info(bo, "imported");

	return bo;

destroy_bo:
	drv_bo_destroy(bo);
	return NULL;
}

void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags,
		 struct mapping **map_data, size_t plane)
{
	struct driver *drv = bo->drv;
	uint32_t i;
	uint8_t *addr;
	struct mapping mapping = { 0 };

	assert(rect->width >= 0);
	assert(rect->height >= 0);
	assert(rect->x + rect->width <= drv_bo_get_width(bo));
	assert(rect->y + rect->height <= drv_bo_get_height(bo));
	assert(BO_MAP_READ_WRITE & map_flags);
	/* No CPU access for protected buffers. */
	assert(!(bo->meta.use_flags & BO_USE_PROTECTED));

	if (bo->is_test_buffer)
		return MAP_FAILED;

	mapping.rect = *rect;
	mapping.refcount = 1;

	pthread_mutex_lock(&drv->mappings_lock);

	for (i = 0; i < drv_array_size(drv->mappings); i++) {
		struct mapping *prior = (struct mapping *)drv_array_at_idx(drv->mappings, i);
		if (prior->vma->handle != bo->handle.u32 || prior->vma->map_flags != map_flags)
			continue;

		if (rect->x != prior->rect.x || rect->y != prior->rect.y ||
		    rect->width != prior->rect.width || rect->height != prior->rect.height)
			continue;

		prior->refcount++;
		*map_data = prior;
		goto exact_match;
	}

	for (i = 0; i < drv_array_size(drv->mappings); i++) {
		struct mapping *prior = (struct mapping *)drv_array_at_idx(drv->mappings, i);
		if (prior->vma->handle != bo->handle.u32 || prior->vma->map_flags != map_flags)
			continue;

		prior->vma->refcount++;
		mapping.vma = prior->vma;
		goto success;
	}

	mapping.vma = calloc(1, sizeof(*mapping.vma));
	if (!mapping.vma) {
		*map_data = NULL;
		pthread_mutex_unlock(&drv->mappings_lock);
		return MAP_FAILED;
	}

	memcpy(mapping.vma->map_strides, bo->meta.strides, sizeof(mapping.vma->map_strides));
	addr = drv->backend->bo_map(bo, mapping.vma, map_flags);
	if (addr == MAP_FAILED) {
		*map_data = NULL;
		free(mapping.vma);
		pthread_mutex_unlock(&drv->mappings_lock);
		return MAP_FAILED;
	}

	mapping.vma->refcount = 1;
	mapping.vma->addr = addr;
	mapping.vma->handle = bo->handle.u32;
	mapping.vma->map_flags = map_flags;

success:
	*map_data = drv_array_append(drv->mappings, &mapping);
exact_match:
	drv_bo_invalidate(bo, *map_data);
	addr = (uint8_t *)((*map_data)->vma->addr);
	addr += drv_bo_get_plane_offset(bo, plane);
	pthread_mutex_unlock(&drv->mappings_lock);
	return (void *)addr;
}

int drv_bo_unmap(struct bo *bo, struct mapping *mapping)
{
	struct driver *drv = bo->drv;
	uint32_t i;
	int ret = 0;

	pthread_mutex_lock(&drv->mappings_lock);

	if (--mapping->refcount)
		goto out;

	if (!--mapping->vma->refcount) {
		ret = drv->backend->bo_unmap(bo, mapping->vma);
		free(mapping->vma);
	}

	for (i = 0; i < drv_array_size(drv->mappings); i++) {
		if (mapping == (struct mapping *)drv_array_at_idx(drv->mappings, i)) {
			drv_array_remove(drv->mappings, i);
			break;
		}
	}

out:
	pthread_mutex_unlock(&drv->mappings_lock);
	return ret;
}

bool drv_bo_cached(struct bo *bo)
{
	return bo->meta.cached;
}

int drv_bo_invalidate(struct bo *bo, struct mapping *mapping)
{
	int ret = 0;

	assert(mapping);
	assert(mapping->vma);
	assert(mapping->refcount > 0);
	assert(mapping->vma->refcount > 0);

	if (bo->drv->backend->bo_invalidate)
		ret = bo->drv->backend->bo_invalidate(bo, mapping);

	return ret;
}

int drv_bo_flush(struct bo *bo, struct mapping *mapping)
{
	int ret = 0;

	assert(mapping);
	assert(mapping->vma);
	assert(mapping->refcount > 0);
	assert(mapping->vma->refcount > 0);

	if (bo->drv->backend->bo_flush)
		ret = bo->drv->backend->bo_flush(bo, mapping);

	return ret;
}

int drv_bo_flush_or_unmap(struct bo *bo, struct mapping *mapping)
{
	int ret = 0;

	assert(mapping);
	assert(mapping->vma);
	assert(mapping->refcount > 0);
	assert(mapping->vma->refcount > 0);
	assert(!(bo->meta.use_flags & BO_USE_PROTECTED));

	if (bo->drv->backend->bo_flush)
		ret = bo->drv->backend->bo_flush(bo, mapping);
	else
		ret = drv_bo_unmap(bo, mapping);

	return ret;
}

uint32_t drv_bo_get_width(struct bo *bo)
{
	return bo->meta.width;
}

uint32_t drv_bo_get_height(struct bo *bo)
{
	return bo->meta.height;
}

size_t drv_bo_get_num_planes(struct bo *bo)
{
	return bo->meta.num_planes;
}

union bo_handle drv_bo_get_plane_handle(struct bo *bo, size_t plane)
{
	return bo->handle;
}

#ifndef DRM_RDWR
#define DRM_RDWR O_RDWR
#endif

int drv_bo_get_plane_fd(struct bo *bo, size_t plane)
{

	int ret, fd;
	assert(plane < bo->meta.num_planes);

	if (bo->is_test_buffer)
		return -EINVAL;

	ret = drmPrimeHandleToFD(bo->drv->fd, bo->handle.u32, DRM_CLOEXEC | DRM_RDWR, &fd);

	// Older DRM implementations blocked DRM_RDWR, but gave a read/write mapping anyways
	if (ret)
		ret = drmPrimeHandleToFD(bo->drv->fd, bo->handle.u32, DRM_CLOEXEC, &fd);

	if (ret)
		drv_loge("Failed to get plane fd: %s\n", strerror(errno));

	return (ret) ? ret : fd;
}

uint32_t drv_bo_get_plane_offset(struct bo *bo, size_t plane)
{
	assert(plane < bo->meta.num_planes);
	return bo->meta.offsets[plane];
}

uint32_t drv_bo_get_plane_size(struct bo *bo, size_t plane)
{
	assert(plane < bo->meta.num_planes);
	return bo->meta.sizes[plane];
}

uint32_t drv_bo_get_plane_stride(struct bo *bo, size_t plane)
{
	assert(plane < bo->meta.num_planes);
	return bo->meta.strides[plane];
}

uint64_t drv_bo_get_format_modifier(struct bo *bo)
{
	return bo->meta.format_modifier;
}

uint32_t drv_bo_get_format(struct bo *bo)
{
	return bo->meta.format;
}

uint32_t drv_bo_get_tiling(struct bo *bo)
{
	return bo->meta.tiling;
}

uint64_t drv_bo_get_use_flags(struct bo *bo)
{
	return bo->meta.use_flags;
}

size_t drv_bo_get_total_size(struct bo *bo)
{
	return bo->meta.total_size;
}

void drv_bo_log_info(const struct bo *bo, const char *prefix)
{
	const struct bo_metadata *meta = &bo->meta;

	drv_logd("%s %s bo %p: %dx%d '%c%c%c%c' tiling %d plane %zu mod 0x%" PRIx64
		 " use 0x%" PRIx64 " size %zu\n",
		 prefix, bo->drv->backend->name, bo, meta->width, meta->height, meta->format & 0xff,
		 (meta->format >> 8) & 0xff, (meta->format >> 16) & 0xff,
		 (meta->format >> 24) & 0xff, meta->tiling, meta->num_planes, meta->format_modifier,
		 meta->use_flags, meta->total_size);
	for (uint32_t i = 0; i < meta->num_planes; i++) {
		drv_logd("  bo %p plane %d: offset %d size %d stride %d\n", bo, i, meta->offsets[i],
			 meta->sizes[i], meta->strides[i]);
	}
}

/*
 * Map internal fourcc codes back to standard fourcc codes.
 */
uint32_t drv_get_standard_fourcc(uint32_t fourcc_internal)
{
	return (fourcc_internal == DRM_FORMAT_YVU420_ANDROID) ? DRM_FORMAT_YVU420 : fourcc_internal;
}

void drv_resolve_format_and_use_flags(struct driver *drv, uint32_t format, uint64_t use_flags,
				      uint32_t *out_format, uint64_t *out_use_flags)
{
	assert(drv->backend->resolve_format_and_use_flags);

	drv->backend->resolve_format_and_use_flags(drv, format, use_flags, out_format,
						   out_use_flags);
}

void drv_log_prefix(enum drv_log_level level, const char *prefix, const char *func, int line,
		    const char *format, ...)
{
	char buf[50];
	snprintf(buf, sizeof(buf), "[%s:%s(%d)]", prefix, func, line);

	va_list args;
	va_start(args, format);
#ifdef __ANDROID__
	int prio = ANDROID_LOG_ERROR;
	switch (level) {
	case DRV_LOGV:
		prio = ANDROID_LOG_VERBOSE;
		break;
	case DRV_LOGD:
		prio = ANDROID_LOG_DEBUG;
		break;
	case DRV_LOGI:
		prio = ANDROID_LOG_INFO;
		break;
	case DRV_LOGE:
	default:
		break;
	};
	__android_log_vprint(prio, buf, format, args);
#else
	fprintf(stderr, "%s ", buf);
	vfprintf(stderr, format, args);
#endif
	va_end(args);
}

int drv_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES],
		      uint32_t offsets[DRV_MAX_PLANES], uint64_t *format_modifier)
{
	for (uint32_t plane = 0; plane < bo->meta.num_planes; plane++) {
		strides[plane] = bo->meta.strides[plane];
		offsets[plane] = bo->meta.offsets[plane];
	}
	*format_modifier = bo->meta.format_modifier;

	if (bo->drv->backend->resource_info)
		return bo->drv->backend->resource_info(bo, strides, offsets, format_modifier);

	return 0;
}

uint32_t drv_get_max_texture_2d_size(struct driver *drv)
{
	if (drv->backend->get_max_texture_2d_size)
		return drv->backend->get_max_texture_2d_size(drv);

	return UINT32_MAX;
}
