/*
 * 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 "gstgldebug.h"

#include <glib/gprintf.h>
#include <string.h>

#include "gstglcontext.h"
#include "gstglcontext_private.h"
#include "gstglfuncs.h"

/**
 * SECTION:gstgldebug
 * @short_description: helper routines for dealing with OpenGL debugging
 * @title: OpenGL debugging
 * @see_also: #GstGLContext
 */

#define ASYNC_DEBUG_FILLED (1 << 0)
#define ASYNC_DEBUG_FROZEN (1 << 1)

/* compatibility defines */
#ifndef GL_DEBUG_TYPE_ERROR
#define GL_DEBUG_TYPE_ERROR 0x824C
#endif
#ifndef GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
#endif
#ifndef GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
#endif
#ifndef GL_DEBUG_TYPE_PORTABILITY
#define GL_DEBUG_TYPE_PORTABILITY 0x824F
#endif
#ifndef GL_DEBUG_TYPE_PERFORMANCE
#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
#endif
#ifndef GL_DEBUG_TYPE_MARKER
#define GL_DEBUG_TYPE_MARKER 0x8268
#endif
#ifndef GL_DEBUG_TYPE_OTHER
#define GL_DEBUG_TYPE_OTHER 0x8251
#endif

#ifndef GL_DEBUG_SEVERITY_HIGH
#define GL_DEBUG_SEVERITY_HIGH 0x9146
#endif
#ifndef GL_DEBUG_SEVERITY_MEDIUM
#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
#endif
#ifndef GL_DEBUG_SEVERITY_LOW
#define GL_DEBUG_SEVERITY_LOW 0x9148
#endif
#ifndef GL_DEBUG_SEVERITY_NOTIFICATION
#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
#endif

#ifndef GL_DEBUG_SOURCE_API
#define GL_DEBUG_SOURCE_API 0x8246
#endif
#ifndef GL_DEBUG_SOURCE_WINDOW_SYSTEM
#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
#endif
#ifndef GL_DEBUG_SOURCE_SHADER_COMPILER
#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
#endif
#ifndef GL_DEBUG_SOURCE_THIRD_PARTY
#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
#endif
#ifndef GL_DEBUG_SOURCE_APPLICATION
#define GL_DEBUG_SOURCE_APPLICATION 0x824A
#endif
#ifndef GL_DEBUG_SOURCE_OTHER
#define GL_DEBUG_SOURCE_OTHER 0x824B
#endif

GST_DEBUG_CATEGORY_STATIC (gst_performance);
#define GST_CAT_DEFAULT gst_gl_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
GST_DEBUG_CATEGORY_STATIC (default_debug);
GST_DEBUG_CATEGORY_STATIC (gst_gl_marker_debug);

static void
_init_debug (void)
{
  static volatile gsize _init = 0;

  if (g_once_init_enter (&_init)) {
    GST_DEBUG_CATEGORY_GET (gst_performance, "GST_PERFORMANCE");
    GST_DEBUG_CATEGORY_GET (gst_gl_debug, "gldebug");
    GST_DEBUG_CATEGORY_GET (default_debug, "default");
    GST_DEBUG_CATEGORY_INIT (gst_gl_marker_debug, "gldebugmarker", 0,
        "OpenGL Markers");
    g_once_init_leave (&_init, 1);
  }
}

static void
_free_async_debug_data (GstGLAsyncDebug * ad)
{
  if (ad->debug_msg) {
    g_free (ad->debug_msg);
    ad->debug_msg = NULL;
    if (ad->object)
      g_object_unref (ad->object);
    ad->object = NULL;
    ad->state_flags &= ~ASYNC_DEBUG_FILLED;
  }
}

/**
 * gst_gl_async_debug_init:
 * @ad: a #GstGLAsyncDebug
 *
 * Initialize @ad.  Intended for use with #GstGLAsyncDebug's that are embedded
 * in other structs.
 *
 * Since: 1.8
 */
void
gst_gl_async_debug_init (GstGLAsyncDebug * ad)
{
  _init_debug ();

  memset (ad, 0, sizeof (*ad));
}

/**
 * gst_gl_async_debug_unset:
 * @ad: a #GstGLAsyncDebug
 *
 * Unset any dynamically allocated data.  Intended for use with
 * #GstGLAsyncDebug's that are embedded in other structs.
 */
void
gst_gl_async_debug_unset (GstGLAsyncDebug * ad)
{
  gst_gl_async_debug_output_log_msg (ad);

  _free_async_debug_data (ad);

  if (ad->notify)
    ad->notify (ad->user_data);
}

/**
 * gst_gl_async_debug_new: (skip)
 *
 * Free with gst_gl_async_debug_free()
 *
 * Returns: a new #GstGLAsyncDebug
 *
 * Since: 1.8
 */
GstGLAsyncDebug *
gst_gl_async_debug_new (void)
{
  return g_new0 (GstGLAsyncDebug, 1);
}

/**
 * gst_gl_async_debug_free:
 * @ad: a #GstGLAsyncDebug
 *
 * Frees @ad
 *
 * Since: 1.8
 */
void
gst_gl_async_debug_free (GstGLAsyncDebug * ad)
{
  gst_gl_async_debug_unset (ad);
  g_free (ad);
}

/**
 * gst_gl_async_debug_freeze:
 * @ad: a #GstGLAsyncDebug
 *
 * freeze the debug output.  While frozen, any call to
 * gst_gl_async_debug_output_log_msg() will not output any messages but
 * subsequent calls to gst_gl_async_debug_store_log_msg() will overwrite previous
 * messages.
 *
 * Since: 1.8
 */
void
gst_gl_async_debug_freeze (GstGLAsyncDebug * ad)
{
  ad->state_flags |= ASYNC_DEBUG_FROZEN;
}

/**
 * gst_gl_async_debug_thaw:
 * @ad: a #GstGLAsyncDebug
 *
 * unfreeze the debug output.  See gst_gl_async_debug_freeze() for what freezing means
 *
 * Since: 1.8
 */
void
gst_gl_async_debug_thaw (GstGLAsyncDebug * ad)
{
  ad->state_flags &= ~ASYNC_DEBUG_FROZEN;
}

#if !defined(GST_DISABLE_GST_DEBUG)

static inline const gchar *
_debug_severity_to_string (GLenum severity)
{
  switch (severity) {
    case GL_DEBUG_SEVERITY_HIGH:
      return "high";
    case GL_DEBUG_SEVERITY_MEDIUM:
      return "medium";
    case GL_DEBUG_SEVERITY_LOW:
      return "low";
    case GL_DEBUG_SEVERITY_NOTIFICATION:
      return "notification";
    default:
      return "invalid";
  }
}

static inline const gchar *
_debug_source_to_string (GLenum source)
{
  switch (source) {
    case GL_DEBUG_SOURCE_API:
      return "API";
    case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
      return "winsys";
    case GL_DEBUG_SOURCE_SHADER_COMPILER:
      return "shader compiler";
    case GL_DEBUG_SOURCE_THIRD_PARTY:
      return "third party";
    case GL_DEBUG_SOURCE_APPLICATION:
      return "application";
    case GL_DEBUG_SOURCE_OTHER:
      return "other";
    default:
      return "invalid";
  }
}

static inline const gchar *
_debug_type_to_string (GLenum type)
{
  switch (type) {
    case GL_DEBUG_TYPE_ERROR:
      return "error";
    case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
      return "deprecated";
    case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
      return "undefined";
    case GL_DEBUG_TYPE_PORTABILITY:
      return "portability";
    case GL_DEBUG_TYPE_PERFORMANCE:
      return "performance";
    case GL_DEBUG_TYPE_MARKER:
      return "debug marker";
    case GL_DEBUG_TYPE_OTHER:
      return "other";
    default:
      return "invalid";
  }
}

static void GSTGLAPI
_gst_gl_debug_callback (GLenum source, GLenum type, GLuint id, GLenum severity,
    GLsizei length, const gchar * message, gpointer user_data)
{
  GstGLContext *context = user_data;
  const gchar *severity_str = _debug_severity_to_string (severity);
  const gchar *source_str = _debug_source_to_string (source);
  const gchar *type_str = _debug_type_to_string (type);

  _init_debug ();

  switch (type) {
    case GL_DEBUG_TYPE_ERROR:
    case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
      GST_ERROR_OBJECT (context, "%s: GL %s from %s id:%u, %s", severity_str,
          type_str, source_str, id, message);
      break;
    case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
    case GL_DEBUG_TYPE_PORTABILITY:
      GST_FIXME_OBJECT (context, "%s: GL %s from %s id:%u, %s", severity_str,
          type_str, source_str, id, message);
      break;
    case GL_DEBUG_TYPE_PERFORMANCE:
      GST_CAT_DEBUG_OBJECT (gst_performance, context, "%s: GL %s from %s id:%u,"
          " %s", severity_str, type_str, source_str, id, message);
      break;
    default:
      GST_DEBUG_OBJECT (context, "%s: GL %s from %s id:%u, %s", severity_str,
          type_str, source_str, id, message);
      break;
  }
}

G_GNUC_INTERNAL void _gst_gl_debug_enable (GstGLContext * context);

G_GNUC_INTERNAL void
_gst_gl_debug_enable (GstGLContext * context)
{
  const GstGLFuncs *gl = context->gl_vtable;
  GstDebugLevel level;
  GLenum debug_types[8];
  guint i, n = 0;

  _init_debug ();

  if (!gl->DebugMessageCallback) {
    GST_CAT_INFO_OBJECT (gst_gl_context_debug, context,
        "No debugging support available");
    return;
  }

  level = gst_debug_category_get_threshold (gst_gl_debug);

  if (level < GST_LEVEL_ERROR) {
    GST_CAT_INFO_OBJECT (gst_gl_context_debug, context,
        "Disabling GL context debugging (gldebug category debug level < error)");
    return;
  }

  GST_CAT_INFO_OBJECT (gst_gl_context_debug, context,
      "Enabling GL context debugging");

  gl->DebugMessageCallback (_gst_gl_debug_callback, context);
  if (level >= GST_LEVEL_DEBUG) {
    /* enable them all */
    gl->DebugMessageControl (GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0,
        GL_TRUE);
  } else {
    if (level >= GST_LEVEL_FIXME) {
      debug_types[n++] = GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR;
      debug_types[n++] = GL_DEBUG_TYPE_PORTABILITY;
    }
    if (level >= GST_LEVEL_ERROR) {
      debug_types[n++] = GL_DEBUG_TYPE_ERROR;
      debug_types[n++] = GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR;
    }
    g_assert (n < G_N_ELEMENTS (debug_types));
    for (i = 0; i < n; i++) {
      gl->DebugMessageControl (GL_DONT_CARE, debug_types[i], GL_DONT_CARE,
          0, 0, GL_TRUE);
    }
  }
}

/**
 * gst_gl_insert_debug_marker:
 * @context: a #GstGLContext
 * @format: a printf-style format string
 * @...: arguments form @format
 *
 * Inserts a marker into a GL debug stream.  Requires the 'gldebugmarker'
 * debug category to be at least %GST_LEVEL_FIXME.
 *
 * Since: 1.8
 */
void
gst_gl_insert_debug_marker (GstGLContext * context, const gchar * format, ...)
{
  const GstGLFuncs *gl = context->gl_vtable;
  gchar *string;
  gint len;
  va_list args;

  _init_debug ();

  /* are we enabled */
  if (gst_debug_category_get_threshold (gst_gl_marker_debug) < GST_LEVEL_FIXME)
    return;

  va_start (args, format);
  len = gst_info_vasprintf (&string, format, args);
  va_end (args);

  /* gst_info_vasprintf() returns -1 on error, the various debug marker
   * functions take len=-1 to mean null terminated */
  if (len < 0 || string == NULL)
    /* no debug output */
    return;

  if (gl->DebugMessageInsert)
    gl->DebugMessageInsert (GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_MARKER,
        0, GL_DEBUG_SEVERITY_LOW, (gsize) len, string);
  else if (gl->InsertEventMarker)
    gl->InsertEventMarker (len, string);
  else if (gl->StringMarker)
    gl->StringMarker (len, string);

  g_free (string);
}

/**
 * gst_gl_async_debug_store_log_msg_valist:
 * @ad: the #GstGLAsyncDebug to store the message in
 * @cat: the #GstDebugCategory to output the message in
 * @level: the #GstLevel
 * @file: the file where the debug message originates from
 * @function: the function where the debug message originates from
 * @line: the line in @file where the debug message originates from
 * @object: (allow-none): a #GObject to associate with the debug message
 * @format: a printf style format string
 * @varargs: the list of arguments for @format
 *
 * Stores a debug message for later output by gst_gl_async_debug_output_log_msg()
 *
 * Since: 1.8
 */
void
gst_gl_async_debug_store_log_msg_valist (GstGLAsyncDebug * ad,
    GstDebugCategory * cat, GstDebugLevel level, const gchar * file,
    const gchar * function, gint line, GObject * object, const gchar * format,
    va_list varargs)
{
  gst_gl_async_debug_output_log_msg (ad);
  _free_async_debug_data (ad);

  if (G_UNLIKELY (level <= GST_LEVEL_MAX && level <= _gst_debug_min)) {
    if (!cat)
      cat = default_debug;

    ad->cat = cat;
    ad->level = level;
    ad->file = file;
    ad->function = function;
    ad->line = line;
    if (object)
      ad->object = g_object_ref (object);
    else
      ad->object = NULL;

    ad->debug_msg = gst_info_strdup_vprintf (format, varargs);
    ad->state_flags |= ASYNC_DEBUG_FILLED;
  }
}

/**
 * gst_gl_async_debug_output_log_msg:
 * @ad: the #GstGLAsyncDebug to store the message in
 *
 * Outputs a previously stored debug message.
 */
void
gst_gl_async_debug_output_log_msg (GstGLAsyncDebug * ad)
{
  if ((ad->state_flags & ASYNC_DEBUG_FILLED) != 0
      && (ad->state_flags & ASYNC_DEBUG_FROZEN) == 0) {
    gchar *msg = NULL;

    if (ad->callback)
      msg = ad->callback (ad->user_data);

    gst_debug_log (ad->cat, ad->level, ad->file, ad->function, ad->line,
        ad->object, "%s %s", GST_STR_NULL (ad->debug_msg), msg ? msg : "");
    g_free (msg);
    _free_async_debug_data (ad);
  }
}

/**
 * gst_gl_async_debug_store_log_msg:
 * @ad: the #GstGLAsyncDebug to store the message in
 * @cat: the #GstDebugCategory to output the message in
 * @level: the #GstLevel
 * @file: the file where the debug message originates from
 * @function: the function where the debug message originates from
 * @line: the line in @file where the debug message originates from
 * @object: (allow-none): a #GObject to associate with the debug message
 * @format: a printf style format string
 * @...: the list of arguments for @format
 *
 * Stores a debug message for later output by gst_gl_async_debug_output_log_msg()
 *
 * Since: 1.8
 */
void
gst_gl_async_debug_store_log_msg (GstGLAsyncDebug * ad, GstDebugCategory * cat,
    GstDebugLevel level, const gchar * file, const gchar * function, gint line,
    GObject * object, const gchar * format, ...)
{
  va_list varargs;

  if (G_UNLIKELY (level <= GST_LEVEL_MAX && level <= _gst_debug_min)) {
    va_start (varargs, format);
    gst_gl_async_debug_store_log_msg_valist (ad, cat, level, file, function,
        line, object, format, varargs);
    va_end (varargs);
  }
}
#else
G_GNUC_INTERNAL void _gst_gl_debug_enable (GstGLContext * context);
#endif
