/*
 * 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.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;
};

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;
   magma_status_t status =
       magma_virt_create_image(magma_device(device)->connection, &create_info, &image);
   if (status != MAGMA_STATUS_OK) {
      LOG_VERBOSE("magma_virt_create_image failed: %d", status);
      return NULL;
   }

   magma_image_info_t info;
   status = magma_virt_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_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->base.gbm = device;
   bo->base.width = width;
   bo->base.height = height;
   bo->base.format = format;
   bo->base.stride = info.plane_strides[0];
   bo->base.handle.u64 = image;
   bo->base.user_data = NULL;
   bo->base.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_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;
   magma_status_t status =
       magma_import(magma_device(device)->connection, import_data.fds[0], &image);
   if (status != MAGMA_STATUS_OK) {
      LOG_VERBOSE("magma_import failed: %d", status);
      return NULL;
   }

   magma_image_info_t info;
   status = magma_virt_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->base.gbm = device;
   bo->base.width = import_data.width;
   bo->base.height = import_data.height;
   bo->base.format = import_data.format;
   // don't use the given stride
   bo->base.stride = info.plane_strides[0];
   bo->base.handle.u64 = image;
   bo->base.user_data = NULL;
   bo->base.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.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.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_export(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_get_buffer_handle2(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->stride + x * bytes_per_pixel();
   size_t length = (height - 1) * bo->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_get_buffer_size(magma_bo(bo)->image));
      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_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->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_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->width, bo->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_release_connection(magma_device(device)->connection);
   free(magma_device(device));
}

static struct gbm_device* magma_device_create(int fd)
{
   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_create_connection2(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.fd = fd;
   device->base.name = "magma";
   device->base.bo_create = magma_bo_create;
   device->base.bo_import = magma_bo_import;
   device->base.bo_map = magma_bo_map;
   device->base.bo_unmap = magma_bo_unmap;
   device->base.is_format_supported = magma_is_format_supported;
   device->base.get_format_modifier_plane_count = magma_get_format_modifier_plane_count;
   device->base.bo_write = magma_bo_write;
   device->base.bo_get_fd = magma_bo_get_fd;
   device->base.bo_get_planes = magma_bo_get_planes;
   device->base.bo_get_handle = magma_bo_get_handle_for_plane;
   device->base.bo_get_plane_fd = magma_bo_get_plane_fd;
   device->base.bo_get_stride = magma_bo_get_stride;
   device->base.bo_get_offset = magma_bo_get_offset;
   device->base.bo_get_modifier = magma_bo_get_modifier;
   device->base.bo_destroy = magma_bo_destroy;
   device->base.destroy = magma_device_destroy;
   device->base.surface_create = magma_surface_create;
   device->base.surface_destroy = magma_surface_destroy;

   return &device->base;
}

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