/*
 * Copyright © 2021 Google, LLC
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "gbmint.h"

#include <assert.h>
#include <errno.h>
#include <magma/magma.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

#include <drm-uapi/drm_fourcc.h>

#define LOG_VERBOSE(msg, ...)                                                                      \
   if (false)                                                                                      \
   fprintf(stderr, msg, ##__VA_ARGS__)

struct gbm_magma_device {
   struct gbm_device base;
   magma_connection_t connection;
};

struct gbm_magma_bo {
   struct gbm_bo base;
   magma_buffer_t image;
   magma_image_info_t info;
   uint64_t size;
};

static struct gbm_magma_device* magma_device(struct gbm_device* device)
{
   return (struct gbm_magma_device*)device;
}

static struct gbm_magma_bo* magma_bo(struct gbm_bo* bo) { return (struct gbm_magma_bo*)bo; }

/* TODO(fxbug.dev/91126) - support for all image formats */
static int bytes_per_pixel() { return 4; }

static int magma_is_format_supported(struct gbm_device* gbm, uint32_t format, uint32_t usage)
{
   switch (format) {
   case GBM_FORMAT_XRGB8888:
   case GBM_FORMAT_XBGR8888:
   case GBM_FORMAT_RGBX8888:
   case GBM_FORMAT_BGRX8888:
   case GBM_FORMAT_ARGB8888:
   case GBM_FORMAT_ABGR8888:
   case GBM_FORMAT_RGBA8888:
   case GBM_FORMAT_BGRA8888:
      return 1;
   default:
      LOG_VERBOSE("Format not supported: 0x%x\n", format);
      return 0;
   }
}

static int magma_get_format_modifier_plane_count(struct gbm_device* device, uint32_t format,
                                                 uint64_t modifier)
{
   switch (modifier) {
   case I915_FORMAT_MOD_Y_TILED_CCS:
   case I915_FORMAT_MOD_Yf_TILED_CCS:
      return 2;
   default:
      return 1;
   }
}

static struct gbm_bo* magma_bo_create(struct gbm_device* device, uint32_t width, uint32_t height,
                                      uint32_t format, uint32_t usage, const uint64_t* modifiers,
                                      const unsigned int count)
{
   if (count >= MAGMA_MAX_DRM_FORMAT_MODIFIERS) {
      LOG_VERBOSE("count %u >= MAGMA_MAX_DRM_FORMAT_MODIFIERS\n", count);
      return NULL;
   }

   /* DRM formats match GBM formats */
   uint32_t drm_format = format;

   /* gbm_bo_create_with_modifiers doesn't let the user specify usage, so if modifiers are
    * provided we assume the user may want their buffer to be presentable.
    */
   bool presentable = (usage & GBM_BO_USE_SCANOUT) || (count > 0);

   magma_image_create_info_t create_info = {
       .width = width,
       .height = height,
       .drm_format = drm_format,
       .flags = presentable ? MAGMA_IMAGE_CREATE_FLAGS_PRESENTABLE : 0,
   };

   if (usage & GBM_BO_USE_LINEAR) {
      create_info.drm_format_modifiers[0] = DRM_FORMAT_MOD_LINEAR;
      create_info.drm_format_modifiers[1] = DRM_FORMAT_MOD_INVALID;
   } else {
      memcpy(create_info.drm_format_modifiers, modifiers, count * sizeof(uint64_t));
      create_info.drm_format_modifiers[count] = DRM_FORMAT_MOD_INVALID;
   }

   magma_buffer_t image;
   uint64_t size;
   magma_buffer_id_t buffer_id;
   magma_status_t status = magma_virt_connection_create_image2(
       magma_device(device)->connection, &create_info, &size, &image, &buffer_id);
   if (status != MAGMA_STATUS_OK) {
      LOG_VERBOSE("magma_virt_create_image failed: %d", status);
      return NULL;
   }

   magma_image_info_t info;
   status = magma_virt_connection_get_image_info(magma_device(device)->connection, image, &info);
   if (status != MAGMA_STATUS_OK) {
      LOG_VERBOSE("magma_virt_get_image_info failed: %d", status);
      magma_connection_release_buffer(magma_device(device)->connection, image);
      return NULL;
   }

   struct gbm_magma_bo* bo = malloc(sizeof(struct gbm_magma_bo));
   bo->image = image;
   bo->info = info;
   bo->size = size;

   bo->base.gbm = device;
   bo->base.v0.width = width;
   bo->base.v0.height = height;
   bo->base.v0.format = format;
   bo->base.v0.stride = info.plane_strides[0];
   bo->base.v0.handle.u64 = image;
   bo->base.v0.user_data = NULL;
   bo->base.v0.destroy_user_data = NULL;

   return &bo->base;
}

static void magma_bo_destroy(struct gbm_bo* _bo)
{
   struct gbm_magma_bo* bo = magma_bo(_bo);
   struct gbm_magma_device* device = magma_device(bo->base.gbm);

   magma_connection_release_buffer(device->connection, bo->image);

   free(bo);
}

static struct gbm_bo* magma_bo_import(struct gbm_device* device, uint32_t type, void* data,
                                      uint32_t usage)
{
   struct gbm_import_fd_modifier_data import_data = {};

   switch (type) {
   case GBM_BO_IMPORT_FD_MODIFIER: {
      struct gbm_import_fd_modifier_data* fd_data = data;
      if (fd_data->num_fds != 1) {
         LOG_VERBOSE("Unhandled num_fds %d\n", fd_data->num_fds);
         return NULL;
      }
      import_data = *fd_data;
      break;
   }
   case GBM_BO_IMPORT_FD: {
      struct gbm_import_fd_data* fd_data = data;
      import_data.width = fd_data->width;
      import_data.height = fd_data->height;
      import_data.format = fd_data->format;
      import_data.num_fds = 1;
      import_data.fds[0] = fd_data->fd;
      import_data.strides[0] = fd_data->stride;
      import_data.modifier = DRM_FORMAT_MOD_INVALID;
      break;
   }
   /* TODO(fxbug.dev/91126) - support for GBM_BO_IMPORT_WL_BUFFER/GBM_BO_IMPORT_EGL_IMAGE */
   default:
      LOG_VERBOSE("Unhandled import type: %u\n", type);
      return NULL;
   }

   magma_buffer_t image;
   uint64_t size;
   magma_buffer_id_t buffer_id;
   magma_status_t status = magma_connection_import_buffer2(
       magma_device(device)->connection, import_data.fds[0], &size, &image, &buffer_id);
   if (status != MAGMA_STATUS_OK) {
      LOG_VERBOSE("magma_import failed: %d", status);
      return NULL;
   }

   magma_image_info_t info;
   status = magma_virt_connection_get_image_info(magma_device(device)->connection, image, &info);
   if (status != MAGMA_STATUS_OK) {
      LOG_VERBOSE("magma_virt_get_image_info failed: %d", status);
      return NULL;
   }

   struct gbm_magma_bo* bo = malloc(sizeof(struct gbm_magma_bo));
   bo->image = image;
   // don't use the client given modifier
   bo->info = info;
   bo->size = size;

   bo->base.gbm = device;
   bo->base.v0.width = import_data.width;
   bo->base.v0.height = import_data.height;
   bo->base.v0.format = import_data.format;
   // don't use the given stride
   bo->base.v0.stride = info.plane_strides[0];
   bo->base.v0.handle.u64 = image;
   bo->base.v0.user_data = NULL;
   bo->base.v0.destroy_user_data = NULL;

   return &bo->base;
}

static int magma_bo_get_planes(struct gbm_bo* bo)
{
   return magma_get_format_modifier_plane_count(bo->gbm, magma_bo(bo)->base.v0.format,
                                                magma_bo(bo)->info.drm_format_modifier);
}

static union gbm_bo_handle magma_bo_get_handle_for_plane(struct gbm_bo* bo, int plane)
{
   // We don't support more than one memory plane
   if (plane != 0) {
      LOG_VERBOSE("Only one memory plane supported");
      union gbm_bo_handle handle;
      handle.s32 = -1;
      return handle;
   }

   return magma_bo(bo)->base.v0.handle;
}

static uint64_t magma_bo_get_modifier(struct gbm_bo* bo)
{
   return magma_bo(bo)->info.drm_format_modifier;
}

static int find_plane(struct gbm_bo* bo, int plane)
{
   int found_plane = -1;

   for (int i = 0; i < MAGMA_MAX_IMAGE_PLANES; i++) {
      if (i == 0 || magma_bo(bo)->info.plane_offsets[i]) {
         if (++found_plane == plane)
            return i;
      }
   }

   return -1;
}

static uint32_t magma_bo_get_offset(struct gbm_bo* bo, int plane)
{
   int plane_index = find_plane(bo, plane);
   if (plane_index < 0) {
      LOG_VERBOSE("Unhandled plane: %d\n", plane);
      return 0;
   }
   return magma_bo(bo)->info.plane_offsets[plane_index];
}

static uint32_t magma_bo_get_stride(struct gbm_bo* bo, int plane)
{
   int plane_index = find_plane(bo, plane);
   if (plane_index < 0) {
      LOG_VERBOSE("Unhandled plane: %d\n", plane);
      return 0;
   }
   return magma_bo(bo)->info.plane_strides[plane_index];
}

static int magma_bo_get_plane_fd(struct gbm_bo* bo, int plane)
{
   // We don't support more than one memory plane
   if (plane != 0) {
      LOG_VERBOSE("Only one memory plane supported");
      return -1;
   }

   magma_handle_t handle;
   magma_status_t status =
       magma_connection_export_buffer(magma_device(bo->gbm)->connection, magma_bo(bo)->image, &handle);
   if (status != MAGMA_STATUS_OK) {
      LOG_VERBOSE("magma_export failed: %d\n", status);
      return -1;
   }
   int fd = handle;
   return fd;
}

static int magma_bo_get_fd(struct gbm_bo* bo) { return magma_bo_get_plane_fd(bo, 0); }

struct Vma {
   void* addr;
   off_t offset;
   size_t length;
   uint32_t flags;
};

static void* magma_bo_map(struct gbm_bo* bo, uint32_t x, uint32_t y, uint32_t width,
                          uint32_t height, uint32_t flags, uint32_t* stride, void** map_data)
{
   magma_handle_t handle;
   magma_status_t status = magma_buffer_get_handle(magma_bo(bo)->image, &handle);
   if (status != MAGMA_STATUS_OK) {
      LOG_VERBOSE("magma_get_buffer_handle failed: %d", status);
      return MAP_FAILED;
   }

   if (width == 0 || height == 0) {
      LOG_VERBOSE("Invalid width %u or height %u\n", width, height);
      return MAP_FAILED;
   }

   int fd = handle;

   uint32_t map_flags = 0;
   if (flags & GBM_BO_TRANSFER_READ)
      map_flags |= PROT_READ;
   if (flags & GBM_BO_TRANSFER_WRITE)
      map_flags |= PROT_WRITE;

   size_t offset = y * bo->v0.stride + x * bytes_per_pixel();
   size_t length = (height - 1) * bo->v0.stride + width * bytes_per_pixel();

   /* Don't pass offset to mmap because it must be page aligned */
   void* addr = mmap(NULL, offset + length, map_flags, MAP_SHARED, fd, 0 /*offset*/);

   close(fd);

   if (addr == MAP_FAILED) {
      LOG_VERBOSE("mmap failed: errno %d offset %lu length %lu buffer size %lu\n", errno, offset,
                  length, magma_bo(bo)->size);
      return MAP_FAILED;
   }

   struct Vma* vma = malloc(sizeof(struct Vma));
   vma->addr = addr;
   vma->offset = offset;
   vma->length = length;
   vma->flags = flags;

   if ((flags & GBM_BO_TRANSFER_READ) &&
       magma_bo(bo)->info.coherency_domain == MAGMA_COHERENCY_DOMAIN_RAM) {
      magma_status_t status = magma_buffer_clean_cache(magma_bo(bo)->image, vma->offset, vma->length,
                                                MAGMA_CACHE_OPERATION_CLEAN_INVALIDATE);
      if (status != MAGMA_STATUS_OK) {
         LOG_VERBOSE("magma_clean_cache failed: %d\n", status);
      }
   }

   *stride = bo->v0.stride;
   *map_data = vma;

   return (uint8_t*)addr + offset;
}

static void magma_bo_unmap(struct gbm_bo* bo, void* map_data)
{
   struct Vma* vma = map_data;

   if ((vma->flags & GBM_BO_TRANSFER_WRITE) &&
       magma_bo(bo)->info.coherency_domain == MAGMA_COHERENCY_DOMAIN_RAM) {
      magma_status_t status = magma_buffer_clean_cache(magma_bo(bo)->image, vma->offset, vma->length,
                                                MAGMA_CACHE_OPERATION_CLEAN);
      if (status != MAGMA_STATUS_OK) {
         LOG_VERBOSE("magma_clean_cache failed: %d\n", status);
      }
   }

   munmap(vma->addr, vma->length);

   free(vma);
}

static int magma_bo_write(struct gbm_bo* bo, const void* buf, size_t data)
{
   uint32_t stride;
   void* map_data;

   void* addr =
       magma_bo_map(bo, 0, 0, bo->v0.width, bo->v0.height, GBM_BO_TRANSFER_WRITE, &stride, &map_data);
   if (addr == MAP_FAILED)
      return -1;

   memcpy(addr, buf, data);

   magma_bo_unmap(bo, map_data);

   return 0;
}

static struct gbm_surface* magma_surface_create(struct gbm_device* gbm, uint32_t width,
                                                uint32_t height, uint32_t format, uint32_t flags,
                                                const uint64_t* modifiers, const unsigned count)
{
   LOG_VERBOSE("magma_surface_create unimplemented\n");
   assert(false);
   return NULL;
}

static struct gbm_bo* magma_surface_lock_front_buffer(struct gbm_surface* surface)
{
   LOG_VERBOSE("magma_surface_lock_front_buffer unimplemented\n");
   assert(false);
   return NULL;
}

static void magma_surface_release_buffer(struct gbm_surface* surface, struct gbm_bo* bo)
{
   LOG_VERBOSE("magma_surface_release_buffer unimplemented\n");
   assert(false);
}

static int magma_surface_has_free_buffers(struct gbm_surface* surface)
{
   LOG_VERBOSE("magma_surface_has_free_buffers unimplemented\n");
   assert(false);
   return 0;
}

static void magma_surface_destroy(struct gbm_surface* surface)
{
   LOG_VERBOSE("magma_surface_destroy unimplemented\n");
   assert(false);
}

static void magma_device_destroy(struct gbm_device* device)
{
   magma_connection_release(magma_device(device)->connection);
   free(magma_device(device));
}

static struct gbm_device* magma_device_create(int fd, uint32_t gbm_backend_version)
{
   struct gbm_magma_device* device = calloc(1, sizeof(struct gbm_magma_device));
   if (!device)
      return NULL;

   magma_device_t magma_device;
   magma_status_t status = magma_device_import(fd, &magma_device);
   if (status != MAGMA_STATUS_OK) {
      LOG_VERBOSE("magma_device_import failed: %d", status);
      return NULL;
   }

   status = magma_device_create_connection(magma_device, &device->connection);
   magma_device_release(magma_device);

   if (status != MAGMA_STATUS_OK) {
      LOG_VERBOSE("magma_create_connection2 failed: %d", status);
      return NULL;
   }

   device->base.v0.fd = fd;
   device->base.v0.name = "magma";
   device->base.v0.bo_create = magma_bo_create;
   device->base.v0.bo_import = magma_bo_import;
   device->base.v0.bo_map = magma_bo_map;
   device->base.v0.bo_unmap = magma_bo_unmap;
   device->base.v0.is_format_supported = magma_is_format_supported;
   device->base.v0.get_format_modifier_plane_count = magma_get_format_modifier_plane_count;
   device->base.v0.bo_write = magma_bo_write;
   device->base.v0.bo_get_fd = magma_bo_get_fd;
   device->base.v0.bo_get_planes = magma_bo_get_planes;
   device->base.v0.bo_get_handle = magma_bo_get_handle_for_plane;
   device->base.v0.bo_get_plane_fd = magma_bo_get_plane_fd;
   device->base.v0.bo_get_stride = magma_bo_get_stride;
   device->base.v0.bo_get_offset = magma_bo_get_offset;
   device->base.v0.bo_get_modifier = magma_bo_get_modifier;
   device->base.v0.bo_destroy = magma_bo_destroy;
   device->base.v0.destroy = magma_device_destroy;
   device->base.v0.surface_create = magma_surface_create;
   device->base.v0.surface_destroy = magma_surface_destroy;

   return &device->base;
}

const struct gbm_backend gbm_magma_backend = {.v0={
    .backend_name = "magma",
    .create_device = magma_device_create,
}};
