/*
 * GStreamer
 * Copyright (C) 2018 Carlos Rafael Giani <dv@pseudoterminal.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <unistd.h>
#include <fcntl.h>
#include <gudev/gudev.h>
#include "gstgl_gbm_utils.h"

GST_DEBUG_CATEGORY_EXTERN (gst_gl_gbm_debug);
#define GST_CAT_DEFAULT gst_gl_gbm_debug


const gchar *
gst_gl_gbm_get_name_for_drm_connector (drmModeConnector * connector)
{
  g_assert (connector != NULL);

  switch (connector->connector_type) {
    case DRM_MODE_CONNECTOR_Unknown:
      return "Unknown";
    case DRM_MODE_CONNECTOR_VGA:
      return "VGA";
    case DRM_MODE_CONNECTOR_DVII:
      return "DVI-I";
    case DRM_MODE_CONNECTOR_DVID:
      return "DVI-D";
    case DRM_MODE_CONNECTOR_DVIA:
      return "DVI-A";
    case DRM_MODE_CONNECTOR_Composite:
      return "Composite";
    case DRM_MODE_CONNECTOR_SVIDEO:
      return "S-Video";
    case DRM_MODE_CONNECTOR_LVDS:
      return "LVDS";
    case DRM_MODE_CONNECTOR_Component:
      return "Component";
    case DRM_MODE_CONNECTOR_9PinDIN:
      return "9-Pin DIN";
    case DRM_MODE_CONNECTOR_DisplayPort:
      return "DisplayPort";
    case DRM_MODE_CONNECTOR_HDMIA:
      return "HDMI-A";
    case DRM_MODE_CONNECTOR_HDMIB:
      return "HDMI-B";
    case DRM_MODE_CONNECTOR_TV:
      return "TV";
    case DRM_MODE_CONNECTOR_eDP:
      return "eDP";
    case DRM_MODE_CONNECTOR_VIRTUAL:
      return "Virtual";
    case DRM_MODE_CONNECTOR_DSI:
      return "DSI";
    default:
      return "<unknown>";
  }
}


const gchar *
gst_gl_gbm_get_name_for_drm_encoder (drmModeEncoder * encoder)
{
  switch (encoder->encoder_type) {
    case DRM_MODE_ENCODER_NONE:
      return "none";
    case DRM_MODE_ENCODER_DAC:
      return "DAC";
    case DRM_MODE_ENCODER_TMDS:
      return "TMDS";
    case DRM_MODE_ENCODER_LVDS:
      return "LVDS";
    case DRM_MODE_ENCODER_TVDAC:
      return "TVDAC";
    case DRM_MODE_ENCODER_VIRTUAL:
      return "Virtual";
    case DRM_MODE_ENCODER_DSI:
      return "DSI";
    default:
      return "<unknown>";
  }
}


const gchar *
gst_gl_gbm_format_to_string (guint32 format)
{
  if (format == GBM_BO_FORMAT_XRGB8888)
    format = GBM_FORMAT_XRGB8888;
  if (format == GBM_BO_FORMAT_ARGB8888)
    format = GBM_FORMAT_ARGB8888;

  switch (format) {
    case GBM_FORMAT_C8:
      return "C8";
    case GBM_FORMAT_RGB332:
      return "RGB332";
    case GBM_FORMAT_BGR233:
      return "BGR233";
    case GBM_FORMAT_NV12:
      return "NV12";
    case GBM_FORMAT_XRGB4444:
      return "XRGB4444";
    case GBM_FORMAT_XBGR4444:
      return "XBGR4444";
    case GBM_FORMAT_RGBX4444:
      return "RGBX4444";
    case GBM_FORMAT_BGRX4444:
      return "BGRX4444";
    case GBM_FORMAT_XRGB1555:
      return "XRGB1555";
    case GBM_FORMAT_XBGR1555:
      return "XBGR1555";
    case GBM_FORMAT_RGBX5551:
      return "RGBX5551";
    case GBM_FORMAT_BGRX5551:
      return "BGRX5551";
    case GBM_FORMAT_ARGB4444:
      return "ARGB4444";
    case GBM_FORMAT_ABGR4444:
      return "ABGR4444";
    case GBM_FORMAT_RGBA4444:
      return "RGBA4444";
    case GBM_FORMAT_BGRA4444:
      return "BGRA4444";
    case GBM_FORMAT_ARGB1555:
      return "ARGB1555";
    case GBM_FORMAT_ABGR1555:
      return "ABGR1555";
    case GBM_FORMAT_RGBA5551:
      return "RGBA5551";
    case GBM_FORMAT_BGRA5551:
      return "BGRA5551";
    case GBM_FORMAT_RGB565:
      return "RGB565";
    case GBM_FORMAT_BGR565:
      return "BGR565";
    case GBM_FORMAT_YUYV:
      return "YUYV";
    case GBM_FORMAT_YVYU:
      return "YVYU";
    case GBM_FORMAT_UYVY:
      return "UYVY";
    case GBM_FORMAT_VYUY:
      return "VYUY";
    case GBM_FORMAT_RGB888:
      return "RGB888";
    case GBM_FORMAT_BGR888:
      return "BGR888";
    case GBM_FORMAT_XRGB8888:
      return "XRGB8888";
    case GBM_FORMAT_XBGR8888:
      return "XBGR8888";
    case GBM_FORMAT_RGBX8888:
      return "RGBX8888";
    case GBM_FORMAT_BGRX8888:
      return "BGRX8888";
    case GBM_FORMAT_AYUV:
      return "AYUV";
    case GBM_FORMAT_XRGB2101010:
      return "XRGB2101010";
    case GBM_FORMAT_XBGR2101010:
      return "XBGR2101010";
    case GBM_FORMAT_RGBX1010102:
      return "RGBX1010102";
    case GBM_FORMAT_BGRX1010102:
      return "BGRX1010102";
    case GBM_FORMAT_ARGB8888:
      return "ARGB8888";
    case GBM_FORMAT_ABGR8888:
      return "ABGR8888";
    case GBM_FORMAT_RGBA8888:
      return "RGBA8888";
    case GBM_FORMAT_BGRA8888:
      return "BGRA8888";
    case GBM_FORMAT_ARGB2101010:
      return "ARGB2101010";
    case GBM_FORMAT_ABGR2101010:
      return "ABGR2101010";
    case GBM_FORMAT_RGBA1010102:
      return "RGBA1010102";
    case GBM_FORMAT_BGRA1010102:
      return "BGRA1010102";

    default:
      return "<unknown>";
  }

  return NULL;
}


int
gst_gl_gbm_depth_from_format (guint32 format)
{
  if (format == GBM_BO_FORMAT_XRGB8888)
    format = GBM_FORMAT_XRGB8888;
  if (format == GBM_BO_FORMAT_ARGB8888)
    format = GBM_FORMAT_ARGB8888;

  switch (format) {
    case GBM_FORMAT_C8:
    case GBM_FORMAT_RGB332:
    case GBM_FORMAT_BGR233:
      return 8;

    case GBM_FORMAT_NV12:
    case GBM_FORMAT_XRGB4444:
    case GBM_FORMAT_XBGR4444:
    case GBM_FORMAT_RGBX4444:
    case GBM_FORMAT_BGRX4444:
      return 12;

    case GBM_FORMAT_XRGB1555:
    case GBM_FORMAT_XBGR1555:
    case GBM_FORMAT_RGBX5551:
    case GBM_FORMAT_BGRX5551:
      return 15;

    case GBM_FORMAT_ARGB4444:
    case GBM_FORMAT_ABGR4444:
    case GBM_FORMAT_RGBA4444:
    case GBM_FORMAT_BGRA4444:
    case GBM_FORMAT_ARGB1555:
    case GBM_FORMAT_ABGR1555:
    case GBM_FORMAT_RGBA5551:
    case GBM_FORMAT_BGRA5551:
    case GBM_FORMAT_RGB565:
    case GBM_FORMAT_BGR565:
    case GBM_FORMAT_YUYV:
    case GBM_FORMAT_YVYU:
    case GBM_FORMAT_UYVY:
    case GBM_FORMAT_VYUY:
      return 16;

    case GBM_FORMAT_RGB888:
    case GBM_FORMAT_BGR888:
    case GBM_FORMAT_XRGB8888:
    case GBM_FORMAT_XBGR8888:
    case GBM_FORMAT_RGBX8888:
    case GBM_FORMAT_BGRX8888:
    case GBM_FORMAT_AYUV:
      return 24;

    case GBM_FORMAT_XRGB2101010:
    case GBM_FORMAT_XBGR2101010:
    case GBM_FORMAT_RGBX1010102:
    case GBM_FORMAT_BGRX1010102:
      return 30;

    case GBM_FORMAT_ARGB8888:
    case GBM_FORMAT_ABGR8888:
    case GBM_FORMAT_RGBA8888:
    case GBM_FORMAT_BGRA8888:
    case GBM_FORMAT_ARGB2101010:
    case GBM_FORMAT_ABGR2101010:
    case GBM_FORMAT_RGBA1010102:
    case GBM_FORMAT_BGRA1010102:
      return 32;

    default:
      GST_ERROR ("unknown GBM format %" G_GUINT32_FORMAT, format);
  }

  return 0;
}


int
gst_gl_gbm_bpp_from_format (guint32 format)
{
  if (format == GBM_BO_FORMAT_XRGB8888)
    format = GBM_FORMAT_XRGB8888;
  if (format == GBM_BO_FORMAT_ARGB8888)
    format = GBM_FORMAT_ARGB8888;

  switch (format) {
    case GBM_FORMAT_C8:
    case GBM_FORMAT_RGB332:
    case GBM_FORMAT_BGR233:
      return 8;

    case GBM_FORMAT_NV12:
      return 12;

    case GBM_FORMAT_XRGB4444:
    case GBM_FORMAT_XBGR4444:
    case GBM_FORMAT_RGBX4444:
    case GBM_FORMAT_BGRX4444:
    case GBM_FORMAT_ARGB4444:
    case GBM_FORMAT_ABGR4444:
    case GBM_FORMAT_RGBA4444:
    case GBM_FORMAT_BGRA4444:
    case GBM_FORMAT_XRGB1555:
    case GBM_FORMAT_XBGR1555:
    case GBM_FORMAT_RGBX5551:
    case GBM_FORMAT_BGRX5551:
    case GBM_FORMAT_ARGB1555:
    case GBM_FORMAT_ABGR1555:
    case GBM_FORMAT_RGBA5551:
    case GBM_FORMAT_BGRA5551:
    case GBM_FORMAT_RGB565:
    case GBM_FORMAT_BGR565:
    case GBM_FORMAT_YUYV:
    case GBM_FORMAT_YVYU:
    case GBM_FORMAT_UYVY:
    case GBM_FORMAT_VYUY:
      return 16;

    case GBM_FORMAT_RGB888:
    case GBM_FORMAT_BGR888:
      return 24;

    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:
    case GBM_FORMAT_XRGB2101010:
    case GBM_FORMAT_XBGR2101010:
    case GBM_FORMAT_RGBX1010102:
    case GBM_FORMAT_BGRX1010102:
    case GBM_FORMAT_ARGB2101010:
    case GBM_FORMAT_ABGR2101010:
    case GBM_FORMAT_RGBA1010102:
    case GBM_FORMAT_BGRA1010102:
    case GBM_FORMAT_AYUV:
      return 32;

    default:
      GST_ERROR ("unknown GBM format %" G_GUINT32_FORMAT, format);
  }

  return 0;
}


static void
gst_gl_gbm_drm_fb_destroy_callback (struct gbm_bo *bo, void *data)
{
  int drm_fd = gbm_device_get_fd (gbm_bo_get_device (bo));
  GstGLDRMFramebuffer *fb = (GstGLDRMFramebuffer *) (data);

  if (fb->fb_id)
    drmModeRmFB (drm_fd, fb->fb_id);

  g_slice_free1 (sizeof (GstGLDRMFramebuffer), fb);
}


GstGLDRMFramebuffer *
gst_gl_gbm_drm_fb_get_from_bo (struct gbm_bo *bo)
{
  GstGLDRMFramebuffer *fb;
  int drm_fd;
  guint32 width, height, stride, format, handle;
  int depth, bpp;
  int ret;

  /* We want to use this buffer object (abbr. "bo") as a scanout buffer.
   * To that end, we associate the bo with the DRM by using drmModeAddFB().
   * However, this needs to be called exactly once for the given bo, and the
   * counterpart, drmModeRmFB(), needs to be called when the bo is cleaned up.
   *
   * To fulfill these requirements, add extra framebuffer information to the
   * bo as "user data". This way, if this user data pointer is NULL, it means
   * that no framebuffer information was generated yet & the bo was not set
   * as a scanout buffer with drmModeAddFB() yet, and we have perform these
   * steps. Otherwise, if it is non-NULL, we know we do not have to set up
   * anything (since it was done already) and just return the pointer to the
   * framebuffer information. */
  fb = (GstGLDRMFramebuffer *) (gbm_bo_get_user_data (bo));
  if (fb != NULL) {
    /* The bo was already set up as a scanout framebuffer. Just
     * return the framebuffer information. */
    return fb;
  }

  /* If this point is reached, then we have to setup the bo as a
   * scanout framebuffer. */

  drm_fd = gbm_device_get_fd (gbm_bo_get_device (bo));

  fb = g_slice_alloc0 (sizeof (GstGLDRMFramebuffer));
  fb->bo = bo;

  width = gbm_bo_get_width (bo);
  height = gbm_bo_get_height (bo);
  stride = gbm_bo_get_stride (bo);
  format = gbm_bo_get_format (bo);
  handle = gbm_bo_get_handle (bo).u32;

  depth = gst_gl_gbm_depth_from_format (format);
  bpp = gst_gl_gbm_bpp_from_format (format);

  GST_DEBUG ("Attempting to add GBM BO as scanout framebuffer width/height: %"
      G_GUINT32_FORMAT "/%" G_GUINT32_FORMAT " pixels  stride: %"
      G_GUINT32_FORMAT " bytes  format: %s  depth: %d bits  total bpp: %d bits",
      width, height, stride, gst_gl_gbm_format_to_string (format), depth, bpp);

  /* Set the bo as a scanout framebuffer */
  ret = drmModeAddFB (drm_fd, width, height, depth, bpp, stride, handle,
      &fb->fb_id);
  if (ret != 0) {
    GST_ERROR ("Failed to add GBM BO as scanout framebuffer: %s (%d)",
        g_strerror (errno), errno);
    g_slice_free1 (sizeof (GstGLDRMFramebuffer), fb);
    return NULL;
  }

  /* Add the framebuffer information to the bo as user data, and also install a callback
   * that cleans up this extra information whenever the bo itself is discarded */
  gbm_bo_set_user_data (bo, fb, gst_gl_gbm_drm_fb_destroy_callback);

  return fb;
}


int
gst_gl_gbm_find_and_open_drm_node (void)
{
  /* In here we use GUDev to try to autodetect the GPU */

  int drm_fd = -1;
  GUdevClient *gudev_client = NULL;
  GUdevEnumerator *gudev_enum = NULL;
  GList *devlist = NULL;
  GList *deventry = NULL;
  const gchar *subsystems[2] = { "drm", NULL };

  gudev_client = g_udev_client_new (subsystems);
  if (gudev_client == NULL) {
    GST_ERROR ("Could not create gudev client");
    goto cleanup;
  }
  GST_DEBUG ("Created gudev client");

  gudev_enum = g_udev_enumerator_new (gudev_client);
  if (gudev_enum == NULL) {
    GST_ERROR ("Could not create gudev enumerator");
    goto cleanup;
  }
  GST_DEBUG ("Created gudev enumerator");

  /* TODO: To be 100% sure we pick the right device, also check
   * if this is a GPU, because a pure scanout device could also
   * have a DRM subsystem for example. However, currently it is
   * unclear how to do that. By trying to create an EGL context? */
  g_udev_enumerator_add_match_subsystem (gudev_enum, "drm");
  devlist = g_udev_enumerator_execute (gudev_enum);
  GST_DEBUG ("Scanned for udev devices with a drm subsytem");

  if (devlist == NULL) {
    GST_WARNING ("Found no matching DRM devices");
    goto cleanup;
  }
  GST_DEBUG ("Got %u potentially matching device(s)", g_list_length (devlist));

  for (deventry = devlist; deventry != NULL; deventry = deventry->next) {
    GUdevDevice *gudevice = G_UDEV_DEVICE (deventry->data);
    const gchar *devnode = g_udev_device_get_device_file (gudevice);

    if ((devnode == NULL) || !g_str_has_prefix (devnode, "/dev/dri/card"))
      continue;

    GST_DEBUG ("Found DRM device with device node \"%s\"", devnode);

    drm_fd = open (devnode, O_RDWR | O_CLOEXEC);
    if (drm_fd < 0) {
      GST_WARNING ("Cannot open device node \"%s\": %s (%d)", devnode,
          g_strerror (errno), errno);
      continue;
    }

    GST_DEBUG ("Device node \"%s\" is a valid DRM device node", devnode);
    break;
  }


done:

  if (devlist != NULL) {
    g_list_free_full (devlist, g_object_unref);
    devlist = NULL;
    GST_DEBUG ("Cleaned up device list");
  }

  if (gudev_enum != NULL) {
    g_object_unref (G_OBJECT (gudev_enum));
    gudev_enum = NULL;
    GST_DEBUG ("Cleaned up gudev enumerator");
  }

  if (gudev_client != NULL) {
    g_object_unref (G_OBJECT (gudev_client));
    gudev_client = NULL;
    GST_DEBUG ("Cleaned up gudev client");
  }

  return drm_fd;


cleanup:

  if (drm_fd >= 0) {
    close (drm_fd);
    drm_fd = -1;
  }

  goto done;
}
