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

#include "gl.h"
#include "gstglfuncs.h"
#include "gstglsl_private.h"

#ifndef GL_GEOMETRY_SHADER
#define GL_GEOMETRY_SHADER        0x8DD9
#endif
#ifndef GL_COMPUTE_SHADER
#define GL_COMPUTE_SHADER         0x91B9
#endif
#ifndef GL_TESS_CONTROL_SHADER
#define GL_TESS_CONTROL_SHADER    0x8E88
#endif
#ifndef GL_TESS_EVALUATION_SHADER
#define GL_TESS_EVALUATION_SHADER 0x8E87
#endif

/**
 * SECTION:gstglslstage
 * @short_description: object for dealing with OpenGL shader stages
 * @title: GstGLSLStage
 * @see_also: #GstGLShader
 *
 * #GstGLSLStage holds and represents a single OpenGL shader stage.
 */

static const gchar *es2_version_header = "#version 100\n";

GST_DEBUG_CATEGORY_STATIC (gst_glsl_stage_debug);
#define GST_CAT_DEFAULT gst_glsl_stage_debug

G_DEFINE_TYPE_WITH_CODE (GstGLSLStage, gst_glsl_stage, GST_TYPE_OBJECT,
    GST_DEBUG_CATEGORY_INIT (gst_glsl_stage_debug, "glslstage", 0,
        "GLSL Stage");
    );

#define GST_GLSL_STAGE_GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GLSL_STAGE, GstGLSLStagePrivate))

struct _GstGLSLStagePrivate
{
  GstGLSLFuncs vtable;

  GLenum type;
  GLhandleARB handle;
  GstGLSLVersion version;
  GstGLSLProfile profile;
  gchar **strings;
  gint n_strings;

  gboolean compiled;
};

static void
gst_glsl_stage_finalize (GObject * object)
{
  GstGLSLStage *stage = GST_GLSL_STAGE (object);
  gint i;

  if (stage->context) {
    gst_object_unref (stage->context);
    stage->context = NULL;
  }

  for (i = 0; i < stage->priv->n_strings; i++) {
    g_free (stage->priv->strings[i]);
  }
  g_free (stage->priv->strings);
  stage->priv->strings = NULL;

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

static void
gst_glsl_stage_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_glsl_stage_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

}

static void
gst_glsl_stage_class_init (GstGLSLStageClass * klass)
{
  GObjectClass *obj_class = G_OBJECT_CLASS (klass);

  g_type_class_add_private (klass, sizeof (GstGLSLStagePrivate));

  obj_class->finalize = gst_glsl_stage_finalize;
  obj_class->set_property = gst_glsl_stage_set_property;
  obj_class->get_property = gst_glsl_stage_get_property;
}

static void
gst_glsl_stage_init (GstGLSLStage * stage)
{
  stage->priv = GST_GLSL_STAGE_GET_PRIVATE (stage);
}

static gboolean
_is_valid_shader_type (GLenum type)
{
  switch (type) {
    case GL_VERTEX_SHADER:
    case GL_FRAGMENT_SHADER:
    case GL_TESS_CONTROL_SHADER:
    case GL_TESS_EVALUATION_SHADER:
    case GL_GEOMETRY_SHADER:
    case GL_COMPUTE_SHADER:
      return TRUE;
    default:
      return FALSE;
  }
}

static const gchar *
_shader_type_to_string (GLenum type)
{
  switch (type) {
    case GL_VERTEX_SHADER:
      return "vertex";
    case GL_FRAGMENT_SHADER:
      return "fragment";
    case GL_TESS_CONTROL_SHADER:
      return "tesselation control";
    case GL_TESS_EVALUATION_SHADER:
      return "tesselation evaluation";
    case GL_GEOMETRY_SHADER:
      return "geometry";
    case GL_COMPUTE_SHADER:
      return "compute";
    default:
      return "unknown";
  }
}

static gboolean
_ensure_shader (GstGLSLStage * stage)
{
  if (stage->priv->handle)
    return TRUE;

  if (!(stage->priv->handle =
          stage->priv->vtable.CreateShader (stage->priv->type)))
    return FALSE;

  return stage->priv->handle != 0;
}

/**
 * gst_glsl_stage_new_with_strings:
 * @context: a #GstGLContext
 * @type: the GL enum shader stage type
 * @version: the #GstGLSLVersion
 * @profile: the #GstGLSLProfile
 * @n_strings: the number of strings in @str
 * @str: an array of strings concatted together to produce a shader
 *
 * Returns: (transfer floating): a new #GstGLSLStage of the specified @type
 *
 * Since: 1.8
 */
GstGLSLStage *
gst_glsl_stage_new_with_strings (GstGLContext * context, guint type,
    GstGLSLVersion version, GstGLSLProfile profile, gint n_strings,
    const gchar ** str)
{
  GstGLSLStage *stage;

  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), NULL);
  g_return_val_if_fail (_is_valid_shader_type (type), NULL);

  stage = g_object_new (GST_TYPE_GLSL_STAGE, NULL);
  /* FIXME: GInittable */
  if (!_gst_glsl_funcs_fill (&stage->priv->vtable, context)) {
    gst_object_unref (stage);
    return NULL;
  }

  stage->context = gst_object_ref (context);
  stage->priv->type = type;
  if (!gst_glsl_stage_set_strings (stage, version, profile, n_strings, str)) {
    gst_object_unref (stage);
    return NULL;
  }

  return stage;
}

/**
 * gst_glsl_stage_new_with_string:
 * @context: a #GstGLContext
 * @type: the GL enum shader stage type
 * @version: the #GstGLSLVersion
 * @profile: the #GstGLSLProfile
 * @str: a shader string
 *
 * Returns: (transfer floating): a new #GstGLSLStage of the specified @type
 *
 * Since: 1.8
 */
GstGLSLStage *
gst_glsl_stage_new_with_string (GstGLContext * context, guint type,
    GstGLSLVersion version, GstGLSLProfile profile, const gchar * str)
{
  return gst_glsl_stage_new_with_strings (context, type, version, profile, 1,
      &str);
}

/**
 * gst_glsl_stage_new:
 * @context: a #GstGLContext
 * @type: the GL enum shader stage type
 *
 * Returns: (transfer floating): a new #GstGLSLStage of the specified @type
 *
 * Since: 1.8
 */
GstGLSLStage *
gst_glsl_stage_new (GstGLContext * context, guint type)
{
  return gst_glsl_stage_new_with_string (context, type, GST_GLSL_VERSION_NONE,
      GST_GLSL_PROFILE_NONE, NULL);
}

/**
 * gst_glsl_stage_new_with_default_vertex:
 * @context: a #GstGLContext
 *
 * Returns: (transfer floating): a new #GstGLSLStage with the default vertex shader
 *
 * Since: 1.8
 */
GstGLSLStage *
gst_glsl_stage_new_default_vertex (GstGLContext * context)
{
  return gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER,
      GST_GLSL_VERSION_NONE,
      GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
      gst_gl_shader_string_vertex_default);
}

/**
 * gst_glsl_stage_new_with_default_fragment:
 * @context: a #GstGLContext
 *
 * Returns: (transfer floating): a new #GstGLSLStage with the default fragment shader
 *
 * Since: 1.8
 */
GstGLSLStage *
gst_glsl_stage_new_default_fragment (GstGLContext * context)
{
  return gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
      GST_GLSL_VERSION_NONE,
      GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
      gst_gl_shader_string_fragment_default);
}

/**
 * gst_glsl_stage_set_strings:
 * @stage: a #GstGLSLStage
 * @version: a #GstGLSLVersion
 * @profile: a #GstGLSLProfile
 * @n_strings: number of strings in @str
 * @str: (transfer none): a GLSL shader string
 *
 * Replaces the current shader string with @str.
 *
 * Since: 1.8
 */
gboolean
gst_glsl_stage_set_strings (GstGLSLStage * stage, GstGLSLVersion version,
    GstGLSLProfile profile, gint n_strings, const gchar ** str)
{
  gint i;

  g_return_val_if_fail (GST_IS_GLSL_STAGE (stage), FALSE);
  g_return_val_if_fail (n_strings > 0, FALSE);
  g_return_val_if_fail (str != NULL, FALSE);

  if (!gst_gl_context_supports_glsl_profile_version (stage->context, version,
          profile)) {
    const gchar *version_str = gst_glsl_version_to_string (version);
    const gchar *profile_str = gst_glsl_profile_to_string (profile);
    GST_ERROR_OBJECT (stage, "GL context does not support version %s and "
        "profile %s", version_str, profile_str);
    return FALSE;
  }

  stage->priv->version = version;
  stage->priv->profile = profile;

  for (i = 0; i < stage->priv->n_strings; i++) {
    g_free (stage->priv->strings[i]);
  }

  if (stage->priv->n_strings < n_strings) {
    /* only realloc if we need more space */
    g_free (stage->priv->strings);
    stage->priv->strings = g_new0 (gchar *, n_strings);
  }

  for (i = 0; i < n_strings; i++)
    stage->priv->strings[i] = g_strdup (str[i]);
  stage->priv->n_strings = n_strings;

  return TRUE;
}

/**
 * gst_glsl_stage_get_shader_type:
 * @stage: a #GstGLSLStage
 *
 * Returns: The GL shader type for this shader stage
 *
 * Since: 1.8
 */
guint
gst_glsl_stage_get_shader_type (GstGLSLStage * stage)
{
  g_return_val_if_fail (GST_IS_GLSL_STAGE (stage), 0);

  return stage->priv->type;
}

/**
 * gst_glsl_stage_get_handle:
 * @stage: a #GstGLSLStage
 *
 * Returns: The GL handle for this shader stage
 *
 * Since: 1.8
 */
guint
gst_glsl_stage_get_handle (GstGLSLStage * stage)
{
  g_return_val_if_fail (GST_IS_GLSL_STAGE (stage), 0);
  g_return_val_if_fail (stage->priv->compiled, 0);

  return stage->priv->handle;
}

/**
 * gst_glsl_stage_get_version:
 * @stage: a #GstGLSLStage
 *
 * Returns: The GLSL version for the current shader stage
 *
 * Since: 1.8
 */
GstGLSLVersion
gst_glsl_stage_get_version (GstGLSLStage * stage)
{
  g_return_val_if_fail (GST_IS_GLSL_STAGE (stage), 0);

  return stage->priv->version;
}

/**
 * gst_glsl_stage_get_profile:
 * @stage: a #GstGLSLStage
 *
 * Returns: The GLSL profile for the current shader stage
 *
 * Since: 1.8
 */
GstGLSLProfile
gst_glsl_stage_get_profile (GstGLSLStage * stage)
{
  g_return_val_if_fail (GST_IS_GLSL_STAGE (stage), 0);

  return stage->priv->profile;
}

static void
_maybe_prepend_version (GstGLSLStage * stage, gchar ** shader_str,
    gint * n_vertex_sources, const gchar *** vertex_sources)
{
  gint n = *n_vertex_sources;
  gboolean add_header = FALSE;
  gint i, j;

  /* FIXME: this all an educated guess */
  if (gst_gl_context_check_gl_version (stage->context, GST_GL_API_OPENGL3, 3, 0)
      && (stage->priv->profile & GST_GLSL_PROFILE_ES) != 0
      && !_gst_glsl_shader_string_find_version (shader_str[0])) {
    add_header = TRUE;
    n++;
  }

  *vertex_sources = g_malloc0 (n * sizeof (gchar *));

  i = 0;
  if (add_header)
    (*vertex_sources)[i++] = es2_version_header;

  for (j = 0; j < stage->priv->n_strings; i++, j++)
    (*vertex_sources)[i] = shader_str[j];
  *n_vertex_sources = n;
}

struct compile
{
  GstGLSLStage *stage;
  GError **error;
  gboolean result;
};

static void
_compile_shader (GstGLContext * context, struct compile *data)
{
  GstGLSLStagePrivate *priv = data->stage->priv;
  GstGLSLFuncs *vtable = &data->stage->priv->vtable;
  const GstGLFuncs *gl = context->gl_vtable;
  const gchar **vertex_sources;
  gchar info_buffer[2048];
  gint n_vertex_sources;
  GLint status;
  gint len;
  gint i;

  if (data->stage->priv->compiled) {
    data->result = TRUE;
    return;
  }

  if (!_ensure_shader (data->stage)) {
    g_set_error (data->error, GST_GLSL_ERROR, GST_GLSL_ERROR_COMPILE,
        "Failed to create shader object");
    data->result = FALSE;
    return;
  }

  n_vertex_sources = data->stage->priv->n_strings;
  _maybe_prepend_version (data->stage, priv->strings, &n_vertex_sources,
      &vertex_sources);

  GST_TRACE_OBJECT (data->stage, "compiling shader:");
  for (i = 0; i < n_vertex_sources; i++) {
    GST_TRACE_OBJECT (data->stage, "%s", vertex_sources[i]);
  }

  gl->ShaderSource (priv->handle, n_vertex_sources,
      (const gchar **) vertex_sources, NULL);
  gl->CompileShader (priv->handle);
  g_free (vertex_sources);
  /* FIXME: supported threaded GLSL compilers and don't destroy compilation
   * performance by getting the compilation result directly after compilation */
  status = GL_FALSE;
  vtable->GetShaderiv (priv->handle, GL_COMPILE_STATUS, &status);

  len = 0;
  vtable->GetShaderInfoLog (priv->handle, sizeof (info_buffer) - 1, &len,
      info_buffer);
  info_buffer[len] = '\0';

  if (status != GL_TRUE) {
    GST_ERROR_OBJECT (data->stage, "%s shader compilation failed:%s",
        _shader_type_to_string (priv->type), info_buffer);

    g_set_error (data->error, GST_GLSL_ERROR, GST_GLSL_ERROR_COMPILE,
        "%s shader compilation failed:%s",
        _shader_type_to_string (priv->type), info_buffer);

    vtable->DeleteShader (priv->handle);
    data->result = FALSE;
    return;
  } else if (len > 1) {
    GST_FIXME_OBJECT (data->stage, "%s shader info log:%s",
        _shader_type_to_string (priv->type), info_buffer);
  }

  data->result = TRUE;
}

/**
 * gst_glsl_stage_compile:
 * @stage: a #GstGLSLStage
 * @error: a #GError to use on failure
 *
 * Returns: whether the compilation suceeded
 *
 * Since: 1.8
 */
gboolean
gst_glsl_stage_compile (GstGLSLStage * stage, GError ** error)
{
  struct compile data;

  g_return_val_if_fail (GST_IS_GLSL_STAGE (stage), FALSE);

  if (!stage->priv->strings) {
    g_set_error (error, GST_GLSL_ERROR, GST_GLSL_ERROR_COMPILE,
        "No shader source to compile");
    return FALSE;
  }

  data.stage = stage;
  data.error = error;

  gst_gl_context_thread_add (stage->context,
      (GstGLContextThreadFunc) _compile_shader, &data);

  stage->priv->compiled = TRUE;

  return data.result;
}
