/*
 * GStreamer
 * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
 *
 * 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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "vkinstance.h"
#include "vkutils_private.h"

#include <string.h>

#define APP_SHORT_NAME "GStreamer"

static const char *instance_validation_layers[] = {
  "VK_LAYER_GOOGLE_threading",
  "VK_LAYER_LUNARG_mem_tracker",
  "VK_LAYER_LUNARG_object_tracker",
  "VK_LAYER_LUNARG_draw_state",
  "VK_LAYER_LUNARG_param_checker",
  "VK_LAYER_LUNARG_swapchain",
  "VK_LAYER_LUNARG_device_limits",
  "VK_LAYER_LUNARG_image",
};

#define GST_CAT_DEFAULT gst_vulkan_instance_debug
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
GST_DEBUG_CATEGORY (GST_VULKAN_DEBUG_CAT);
GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT);

enum
{
  SIGNAL_0,
  SIGNAL_CREATE_DEVICE,
  LAST_SIGNAL
};

static guint gst_vulkan_instance_signals[LAST_SIGNAL] = { 0 };

#define gst_vulkan_instance_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstVulkanInstance, gst_vulkan_instance,
    GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT,
        "vulkaninstance", 0, "Vulkan Instance");
    GST_DEBUG_CATEGORY_INIT (GST_VULKAN_DEBUG_CAT,
        "vulkandebug", 0, "Vulkan Debug");
    GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT"));

static void gst_vulkan_instance_finalize (GObject * object);

struct _GstVulkanInstancePrivate
{
  gboolean opened;
};

GstVulkanInstance *
gst_vulkan_instance_new (void)
{
  return g_object_new (GST_TYPE_VULKAN_INSTANCE, NULL);
}

static void
gst_vulkan_instance_init (GstVulkanInstance * instance)
{
  instance->priv = G_TYPE_INSTANCE_GET_PRIVATE ((instance),
      GST_TYPE_VULKAN_INSTANCE, GstVulkanInstancePrivate);
}

static void
gst_vulkan_instance_class_init (GstVulkanInstanceClass * klass)
{
  gst_vulkan_memory_init_once ();
  gst_vulkan_image_memory_init_once ();
  gst_vulkan_buffer_memory_init_once ();

  g_type_class_add_private (klass, sizeof (GstVulkanInstancePrivate));

  /**
   * GstVulkanInstance::create-device:
   * @object: the #GstVulkanDisplay
   *
   * Overrides the #GstVulkanDevice creation mechanism.
   * It can be called from any thread.
   *
   * Returns: the newly created #GstVulkanDevice.
   */
  gst_vulkan_instance_signals[SIGNAL_CREATE_DEVICE] =
      g_signal_new ("create-device", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
      GST_TYPE_VULKAN_DEVICE, 0);

  G_OBJECT_CLASS (klass)->finalize = gst_vulkan_instance_finalize;
}

static void
gst_vulkan_instance_finalize (GObject * object)
{
  GstVulkanInstance *instance = GST_VULKAN_INSTANCE (object);

  if (instance->priv->opened) {
    if (instance->dbgDestroyDebugReportCallback)
      instance->dbgDestroyDebugReportCallback (instance->instance,
          instance->msg_callback, NULL);

    g_free (instance->physical_devices);
  }
  instance->priv->opened = FALSE;

  if (instance->instance)
    vkDestroyInstance (instance->instance, NULL);
  instance->instance = NULL;

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static VkBool32
_gst_vk_debug_callback (VkDebugReportFlagsEXT msgFlags,
    VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location,
    int32_t msgCode, const char *pLayerPrefix, const char *pMsg,
    void *pUserData)
{
  if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
    GST_CAT_ERROR (GST_VULKAN_DEBUG_CAT, "[%s] Code %d : %s", pLayerPrefix,
        msgCode, pMsg);
  } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
    GST_CAT_WARNING (GST_VULKAN_DEBUG_CAT, "[%s] Code %d : %s", pLayerPrefix,
        msgCode, pMsg);
  } else if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
    GST_CAT_LOG (GST_VULKAN_DEBUG_CAT, "[%s] Code %d : %s", pLayerPrefix,
        msgCode, pMsg);
  } else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
    GST_CAT_FIXME (GST_VULKAN_DEBUG_CAT, "[%s] Code %d : %s", pLayerPrefix,
        msgCode, pMsg);
  } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
    GST_CAT_TRACE (GST_VULKAN_DEBUG_CAT, "[%s] Code %d : %s", pLayerPrefix,
        msgCode, pMsg);
  } else {
    return FALSE;
  }

  /*
   * false indicates that layer should not bail-out of an
   * API call that had validation failures. This may mean that the
   * app dies inside the driver due to invalid parameter(s).
   * That's what would happen without validation layers, so we'll
   * keep that behavior here.
   */
  return FALSE;
}

gboolean
gst_vulkan_instance_open (GstVulkanInstance * instance, GError ** error)
{
  VkExtensionProperties *instance_extensions;
  char *extension_names[64];    /* FIXME: make dynamic */
  VkLayerProperties *instance_layers;
  uint32_t instance_extension_count = 0;
  uint32_t enabled_extension_count = 0;
  uint32_t instance_layer_count = 0;
  uint32_t enabled_layer_count = 0;
  gchar **enabled_layers;
  VkResult err;

  GST_OBJECT_LOCK (instance);
  if (instance->priv->opened) {
    GST_OBJECT_UNLOCK (instance);
    return TRUE;
  }

  /* Look for validation layers */
  err = vkEnumerateInstanceLayerProperties (&instance_layer_count, NULL);
  if (gst_vulkan_error_to_g_error (err, error,
          "vKEnumerateInstanceLayerProperties") < 0)
    goto error;

  instance_layers = g_new0 (VkLayerProperties, instance_layer_count);
  err =
      vkEnumerateInstanceLayerProperties (&instance_layer_count,
      instance_layers);
  if (gst_vulkan_error_to_g_error (err, error,
          "vKEnumerateInstanceLayerProperties") < 0) {
    g_free (instance_layers);
    goto error;
  }

  /* TODO: allow outside selection */
  _check_for_all_layers (G_N_ELEMENTS (instance_validation_layers),
      instance_validation_layers, instance_layer_count, instance_layers,
      &enabled_layer_count, &enabled_layers);

  g_free (instance_layers);

  err =
      vkEnumerateInstanceExtensionProperties (NULL, &instance_extension_count,
      NULL);
  if (gst_vulkan_error_to_g_error (err, error,
          "vkEnumerateInstanceExtensionProperties") < 0) {
    g_strfreev (enabled_layers);
    goto error;
  }
  GST_DEBUG_OBJECT (instance, "Found %u extensions", instance_extension_count);

  memset (extension_names, 0, sizeof (extension_names));
  instance_extensions =
      g_new0 (VkExtensionProperties, instance_extension_count);
  err =
      vkEnumerateInstanceExtensionProperties (NULL, &instance_extension_count,
      instance_extensions);
  if (gst_vulkan_error_to_g_error (err, error,
          "vkEnumerateInstanceExtensionProperties") < 0) {
    g_strfreev (enabled_layers);
    g_free (instance_extensions);
    goto error;
  }

  {
    GstVulkanDisplayType display_type;
    gboolean swapchain_ext_found = FALSE;
    gboolean winsys_ext_found = FALSE;
    const gchar *winsys_ext_name;

    display_type = gst_vulkan_display_choose_type (instance);

    winsys_ext_name =
        gst_vulkan_display_type_to_extension_string (display_type);
    if (!winsys_ext_name) {
      GST_WARNING_OBJECT (instance, "No window system extension enabled");
      winsys_ext_found = TRUE;  /* Don't error out completely */
    }

    /* TODO: allow outside selection */
    for (uint32_t i = 0; i < instance_extension_count; i++) {
      GST_TRACE_OBJECT (instance, "checking instance extension %s",
          instance_extensions[i].extensionName);

      if (!g_strcmp0 (VK_KHR_SURFACE_EXTENSION_NAME,
              instance_extensions[i].extensionName)) {
        swapchain_ext_found = TRUE;
        extension_names[enabled_extension_count++] =
            (gchar *) VK_KHR_SURFACE_EXTENSION_NAME;
      }
      if (!g_strcmp0 (VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
              instance_extensions[i].extensionName)) {
        extension_names[enabled_extension_count++] =
            (gchar *) VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
      }
      if (!g_strcmp0 (winsys_ext_name, instance_extensions[i].extensionName)) {
        winsys_ext_found = TRUE;
        extension_names[enabled_extension_count++] = (gchar *) winsys_ext_name;
      }
      g_assert (enabled_extension_count < 64);
    }
    if (!swapchain_ext_found) {
      g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
          "vkEnumerateInstanceExtensionProperties failed to find the required "
          "\"" VK_KHR_SURFACE_EXTENSION_NAME "\" extension");
      g_strfreev (enabled_layers);
      g_free (instance_extensions);
      goto error;
    }
    if (!winsys_ext_found) {
      g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
          "vkEnumerateInstanceExtensionProperties failed to find the required "
          "\"%s\" window system extension", winsys_ext_name);
      g_strfreev (enabled_layers);
      g_free (instance_extensions);
      goto error;
    }
  }

  {
    VkApplicationInfo app = { 0, };
    VkInstanceCreateInfo inst_info = { 0, };

    app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    app.pNext = NULL;
    app.pApplicationName = APP_SHORT_NAME;
    app.applicationVersion = 0;
    app.pEngineName = APP_SHORT_NAME;
    app.engineVersion = 0;
    app.apiVersion = VK_API_VERSION_1_0;

    inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    inst_info.pNext = NULL;
    inst_info.pApplicationInfo = &app;
#if 0
    inst_info.enabledLayerCount = enabled_layer_count;
    inst_info.ppEnabledLayerNames = (const char *const *) enabled_layers;
#else
    inst_info.enabledLayerCount = 0;
    inst_info.ppEnabledLayerNames = NULL;
#endif
    inst_info.enabledExtensionCount = enabled_extension_count;
    inst_info.ppEnabledExtensionNames = (const char *const *) extension_names;

    err = vkCreateInstance (&inst_info, NULL, &instance->instance);
    if (gst_vulkan_error_to_g_error (err, error, "vkCreateInstance") < 0) {
      g_strfreev (enabled_layers);
      g_free (instance_extensions);
      goto error;
    }
  }

  g_free (instance_extensions);
  g_strfreev (enabled_layers);

  err =
      vkEnumeratePhysicalDevices (instance->instance,
      &instance->n_physical_devices, NULL);
  if (gst_vulkan_error_to_g_error (err, error,
          "vkEnumeratePhysicalDevices") < 0)
    goto error;
  g_assert (instance->n_physical_devices > 0);
  instance->physical_devices =
      g_new0 (VkPhysicalDevice, instance->n_physical_devices);
  err =
      vkEnumeratePhysicalDevices (instance->instance,
      &instance->n_physical_devices, instance->physical_devices);
  if (gst_vulkan_error_to_g_error (err, error,
          "vkEnumeratePhysicalDevices") < 0)
    goto error;

  instance->dbgCreateDebugReportCallback = (PFN_vkCreateDebugReportCallbackEXT)
      gst_vulkan_instance_get_proc_address (instance,
      "vkCreateDebugReportCallbackEXT");
  if (!instance->dbgCreateDebugReportCallback) {
    g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
        "Failed to retreive vkCreateDebugReportCallback");
    goto error;
  }
  instance->dbgDestroyDebugReportCallback =
      (PFN_vkDestroyDebugReportCallbackEXT)
      gst_vulkan_instance_get_proc_address (instance,
      "vkDestroyDebugReportCallbackEXT");
  if (!instance->dbgDestroyDebugReportCallback) {
    g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
        "Failed to retreive vkDestroyDebugReportCallback");
    goto error;
  }
  instance->dbgReportMessage = (PFN_vkDebugReportMessageEXT)
      gst_vulkan_instance_get_proc_address (instance,
      "vkDebugReportMessageEXT");
  if (!instance->dbgReportMessage) {
    g_set_error (error, GST_VULKAN_ERROR, VK_ERROR_INITIALIZATION_FAILED,
        "Failed to retreive vkDebugReportMessage");
    goto error;
  }

  {
    VkDebugReportCallbackCreateInfoEXT info = { 0, };

    info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
    info.pNext = NULL;
    info.flags =
        VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT |
        VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT |
        VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
    info.pfnCallback = (PFN_vkDebugReportCallbackEXT) _gst_vk_debug_callback;
    info.pUserData = NULL;

    err =
        instance->dbgCreateDebugReportCallback (instance->instance, &info, NULL,
        &instance->msg_callback);
    if (gst_vulkan_error_to_g_error (err, error,
            "vkCreateDebugReportCallback") < 0)
      goto error;
  }

  instance->priv->opened = TRUE;
  GST_OBJECT_UNLOCK (instance);

  return TRUE;

error:
  {
    GST_OBJECT_UNLOCK (instance);
    return FALSE;
  }
}

gpointer
gst_vulkan_instance_get_proc_address (GstVulkanInstance * instance,
    const gchar * name)
{
  g_return_val_if_fail (GST_IS_VULKAN_INSTANCE (instance), NULL);
  g_return_val_if_fail (instance->instance != NULL, NULL);
  g_return_val_if_fail (name != NULL, NULL);

  GST_TRACE_OBJECT (instance, "%s", name);

  return vkGetInstanceProcAddr (instance->instance, name);
}

GstVulkanDevice *
gst_vulkan_instance_create_device (GstVulkanInstance * instance,
    GError ** error)
{
  GstVulkanDevice *device;

  g_return_val_if_fail (GST_IS_VULKAN_INSTANCE (instance), NULL);

  g_signal_emit (instance, gst_vulkan_instance_signals[SIGNAL_CREATE_DEVICE], 0,
      &device);

  if (!device)
    device = gst_vulkan_device_new (instance);

  if (!gst_vulkan_device_open (device, error)) {
    gst_object_unref (device);
    device = NULL;
  }

  return device;
}

/**
 * gst_context_set_vulkan_instance:
 * @context: a #GstContext
 * @instance: a #GstVulkanInstance
 *
 * Sets @instance on @context
 *
 * Since: 1.10
 */
void
gst_context_set_vulkan_instance (GstContext * context,
    GstVulkanInstance * instance)
{
  GstStructure *s;

  g_return_if_fail (context != NULL);
  g_return_if_fail (gst_context_is_writable (context));

  if (instance)
    GST_CAT_LOG (GST_CAT_CONTEXT,
        "setting GstVulkanInstance(%" GST_PTR_FORMAT ") on context(%"
        GST_PTR_FORMAT ")", instance, context);

  s = gst_context_writable_structure (context);
  gst_structure_set (s, GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR,
      GST_TYPE_VULKAN_INSTANCE, instance, NULL);
}

/**
 * gst_context_get_vulkan_instance:
 * @context: a #GstContext
 * @instance: resulting #GstVulkanInstance
 *
 * Returns: Whether @instance was in @context
 *
 * Since: 1.10
 */
gboolean
gst_context_get_vulkan_instance (GstContext * context,
    GstVulkanInstance ** instance)
{
  const GstStructure *s;
  gboolean ret;

  g_return_val_if_fail (instance != NULL, FALSE);
  g_return_val_if_fail (context != NULL, FALSE);

  s = gst_context_get_structure (context);
  ret = gst_structure_get (s, GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR,
      GST_TYPE_VULKAN_INSTANCE, instance, NULL);

  GST_CAT_LOG (GST_CAT_CONTEXT, "got GstVulkanInstance(%" GST_PTR_FORMAT
      ") from context(%" GST_PTR_FORMAT ")", *instance, context);

  return ret;
}

gboolean
gst_vulkan_instance_handle_context_query (GstElement * element,
    GstQuery * query, GstVulkanInstance ** instance)
{
  gboolean res = FALSE;
  const gchar *context_type;
  GstContext *context, *old_context;

  g_return_val_if_fail (element != NULL, FALSE);
  g_return_val_if_fail (query != NULL, FALSE);
  g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE);
  g_return_val_if_fail (instance != NULL, FALSE);

  gst_query_parse_context_type (query, &context_type);

  if (g_strcmp0 (context_type, GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR) == 0) {
    gst_query_parse_context (query, &old_context);

    if (old_context)
      context = gst_context_copy (old_context);
    else
      context = gst_context_new (GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR, TRUE);

    gst_context_set_vulkan_instance (context, *instance);
    gst_query_set_context (query, context);
    gst_context_unref (context);

    res = *instance != NULL;
  }

  return res;
}

gboolean
gst_vulkan_instance_run_context_query (GstElement * element,
    GstVulkanInstance ** instance)
{
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
  g_return_val_if_fail (instance != NULL, FALSE);

  if (*instance && GST_IS_VULKAN_INSTANCE (*instance))
    return TRUE;

  gst_vulkan_global_context_query (element,
      GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR);

  GST_DEBUG_OBJECT (element, "found instance %p", *instance);

  if (*instance)
    return TRUE;

  return FALSE;
}
