/*
 * 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 <gst/video/gstvideometa.h>

#include <gst/gl/gl.h>

/**
 * SECTION:gstglbasefilter
 * @short_description: #GstBaseTransform subclass for transformin OpenGL resources
 * @title: GstGLBaseFilter
 * @see_also: #GstBaseTransform
 *
 * #GstGLBaseFilter handles the nitty gritty details of retrieving an OpenGL
 * context.  It also provided some wrappers around #GstBaseTransform's
 * start(), stop() and set_caps() virtual methods that ensure an OpenGL context
 * is available and current in the calling thread.
 */

#define GST_CAT_DEFAULT gst_gl_base_filter_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

#define GST_GL_BASE_FILTER_GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_BASE_FILTER, GstGLBaseFilterPrivate))

struct _GstGLBaseFilterPrivate
{
  GstGLContext *other_context;

  gboolean gl_result;
  gboolean gl_started;
};

/* Properties */
enum
{
  PROP_0,
  PROP_CONTEXT
};

#define gst_gl_base_filter_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLBaseFilter, gst_gl_base_filter,
    GST_TYPE_BASE_TRANSFORM, GST_DEBUG_CATEGORY_INIT (gst_gl_base_filter_debug,
        "glbasefilter", 0, "glbasefilter element");
    );

static void gst_gl_base_filter_finalize (GObject * object);
static void gst_gl_base_filter_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_gl_base_filter_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static void gst_gl_base_filter_set_context (GstElement * element,
    GstContext * context);
static GstStateChangeReturn gst_gl_base_filter_change_state (GstElement *
    element, GstStateChange transition);
static gboolean gst_gl_base_filter_query (GstBaseTransform * trans,
    GstPadDirection direction, GstQuery * query);
static void gst_gl_base_filter_reset (GstGLBaseFilter * filter);
static gboolean gst_gl_base_filter_start (GstBaseTransform * bt);
static gboolean gst_gl_base_filter_stop (GstBaseTransform * bt);
static gboolean gst_gl_base_filter_set_caps (GstBaseTransform * bt,
    GstCaps * incaps, GstCaps * outcaps);
static gboolean gst_gl_base_filter_decide_allocation (GstBaseTransform * trans,
    GstQuery * query);

/* GstGLContextThreadFunc */
static void gst_gl_base_filter_gl_start (GstGLContext * context, gpointer data);
static void gst_gl_base_filter_gl_stop (GstGLContext * context, gpointer data);

static void
gst_gl_base_filter_class_init (GstGLBaseFilterClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;

  g_type_class_add_private (klass, sizeof (GstGLBaseFilterPrivate));

  gobject_class = (GObjectClass *) klass;
  element_class = GST_ELEMENT_CLASS (klass);

  gobject_class->finalize = gst_gl_base_filter_finalize;
  gobject_class->set_property = gst_gl_base_filter_set_property;
  gobject_class->get_property = gst_gl_base_filter_get_property;

  GST_BASE_TRANSFORM_CLASS (klass)->query = gst_gl_base_filter_query;
  GST_BASE_TRANSFORM_CLASS (klass)->set_caps = gst_gl_base_filter_set_caps;
  GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_base_filter_start;
  GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_base_filter_stop;
  GST_BASE_TRANSFORM_CLASS (klass)->decide_allocation =
      gst_gl_base_filter_decide_allocation;

  element_class->set_context = gst_gl_base_filter_set_context;
  element_class->change_state = gst_gl_base_filter_change_state;

  g_object_class_install_property (gobject_class, PROP_CONTEXT,
      g_param_spec_object ("context",
          "OpenGL context",
          "Get OpenGL context",
          GST_GL_TYPE_CONTEXT, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  klass->supported_gl_api = GST_GL_API_ANY;
}

static void
gst_gl_base_filter_init (GstGLBaseFilter * filter)
{
  gst_base_transform_set_qos_enabled (GST_BASE_TRANSFORM (filter), TRUE);

  filter->priv = GST_GL_BASE_FILTER_GET_PRIVATE (filter);
}

static void
gst_gl_base_filter_finalize (GObject * object)
{
  GstGLBaseFilter *filter = GST_GL_BASE_FILTER (object);

  gst_caps_replace (&filter->in_caps, NULL);
  gst_caps_replace (&filter->out_caps, NULL);

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

static void
gst_gl_base_filter_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_gl_base_filter_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstGLBaseFilter *filter = GST_GL_BASE_FILTER (object);

  switch (prop_id) {
    case PROP_CONTEXT:
      g_value_set_object (value, filter->context);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_gl_base_filter_set_context (GstElement * element, GstContext * context)
{
  GstGLBaseFilter *filter = GST_GL_BASE_FILTER (element);
  GstGLBaseFilterClass *filter_class = GST_GL_BASE_FILTER_GET_CLASS (filter);

  gst_gl_handle_set_context (element, context, &filter->display,
      &filter->priv->other_context);
  if (filter->display)
    gst_gl_display_filter_gl_api (filter->display,
        filter_class->supported_gl_api);

  GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}

static gboolean
_find_local_gl_context (GstGLBaseFilter * filter)
{
  GstQuery *query;
  GstContext *context;
  const GstStructure *s;

  if (filter->context)
    return TRUE;

  query = gst_query_new_context ("gst.gl.local_context");
  if (!filter->context
      && gst_gl_run_query (GST_ELEMENT (filter), query, GST_PAD_SRC)) {
    gst_query_parse_context (query, &context);
    if (context) {
      s = gst_context_get_structure (context);
      gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &filter->context,
          NULL);
    }
  }
  if (!filter->context
      && gst_gl_run_query (GST_ELEMENT (filter), query, GST_PAD_SINK)) {
    gst_query_parse_context (query, &context);
    if (context) {
      s = gst_context_get_structure (context);
      gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &filter->context,
          NULL);
    }
  }

  GST_DEBUG_OBJECT (filter, "found local context %p", filter->context);

  gst_query_unref (query);

  if (filter->context)
    return TRUE;

  return FALSE;
}

static gboolean
gst_gl_base_filter_query (GstBaseTransform * trans, GstPadDirection direction,
    GstQuery * query)
{
  GstGLBaseFilter *filter = GST_GL_BASE_FILTER (trans);
  GstGLBaseFilterClass *filter_class = GST_GL_BASE_FILTER_GET_CLASS (filter);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_ALLOCATION:
    {
      if (direction == GST_PAD_SINK
          && gst_base_transform_is_passthrough (trans)) {
        _find_local_gl_context (filter);

        return gst_pad_peer_query (GST_BASE_TRANSFORM_SRC_PAD (trans), query);
      }
      break;
    }
    case GST_QUERY_CONTEXT:
    {
      const gchar *context_type;
      GstContext *context, *old_context;
      gboolean ret;

      ret = gst_gl_handle_context_query ((GstElement *) filter, query,
          &filter->display, &filter->priv->other_context);
      if (filter->display)
        gst_gl_display_filter_gl_api (filter->display,
            filter_class->supported_gl_api);

      gst_query_parse_context_type (query, &context_type);

      if (g_strcmp0 (context_type, "gst.gl.local_context") == 0) {
        GstStructure *s;

        gst_query_parse_context (query, &old_context);

        if (old_context)
          context = gst_context_copy (old_context);
        else
          context = gst_context_new ("gst.gl.local_context", FALSE);

        s = gst_context_writable_structure (context);
        gst_structure_set (s, "context", GST_GL_TYPE_CONTEXT, filter->context,
            NULL);
        gst_query_set_context (query, context);
        gst_context_unref (context);

        ret = filter->context != NULL;
      }
      GST_LOG_OBJECT (filter, "context query of type %s %i", context_type, ret);

      if (ret)
        return ret;
      break;
    }
    default:
      break;
  }

  return GST_BASE_TRANSFORM_CLASS (parent_class)->query (trans, direction,
      query);
}

static void
gst_gl_base_filter_reset (GstGLBaseFilter * filter)
{
  GstGLBaseFilterClass *filter_class = GST_GL_BASE_FILTER_GET_CLASS (filter);

  if (filter->context) {
    if (filter_class->gl_stop != NULL) {
      gst_gl_context_thread_add (filter->context, gst_gl_base_filter_gl_stop,
          filter);
    }

    gst_object_unref (filter->context);
    filter->context = NULL;
  }
}

static gboolean
gst_gl_base_filter_start (GstBaseTransform * bt)
{
  return TRUE;
}

static gboolean
gst_gl_base_filter_stop (GstBaseTransform * bt)
{
  GstGLBaseFilter *filter = GST_GL_BASE_FILTER (bt);

  gst_gl_base_filter_reset (filter);

  return TRUE;
}

static void
gst_gl_base_filter_gl_start (GstGLContext * context, gpointer data)
{
  GstGLBaseFilter *filter = GST_GL_BASE_FILTER (data);
  GstGLBaseFilterClass *filter_class = GST_GL_BASE_FILTER_GET_CLASS (filter);

  gst_gl_insert_debug_marker (filter->context,
      "starting element %s", GST_OBJECT_NAME (filter));

  if (filter_class->gl_start) {
    filter->priv->gl_result = filter_class->gl_start (filter);
  } else {
    filter->priv->gl_result = TRUE;
  }

  filter->priv->gl_started |= filter->priv->gl_result;
}

static void
gst_gl_base_filter_gl_stop (GstGLContext * context, gpointer data)
{
  GstGLBaseFilter *filter = GST_GL_BASE_FILTER (data);
  GstGLBaseFilterClass *filter_class = GST_GL_BASE_FILTER_GET_CLASS (filter);

  gst_gl_insert_debug_marker (filter->context,
      "stopping element %s", GST_OBJECT_NAME (filter));

  if (filter->priv->gl_started) {
    if (filter_class->gl_stop)
      filter_class->gl_stop (filter);
  }

  filter->priv->gl_started = FALSE;
}

static void
_gl_set_caps (GstGLContext * context, GstGLBaseFilter * filter)
{
  GstGLBaseFilterClass *filter_class = GST_GL_BASE_FILTER_GET_CLASS (filter);

  if (filter_class->gl_set_caps)
    filter->priv->gl_result =
        filter_class->gl_set_caps (filter, filter->in_caps, filter->out_caps);
}

static gboolean
gst_gl_base_filter_decide_allocation (GstBaseTransform * trans,
    GstQuery * query)
{
  GstGLBaseFilter *filter = GST_GL_BASE_FILTER (trans);
  GstGLBaseFilterClass *filter_class = GST_GL_BASE_FILTER_GET_CLASS (filter);
  GError *error = NULL;
  gboolean new_context = FALSE;

  if (!filter->context)
    new_context = TRUE;

  _find_local_gl_context (filter);

  if (!filter->context) {
    GST_OBJECT_LOCK (filter->display);
    do {
      if (filter->context)
        gst_object_unref (filter->context);
      /* just get a GL context.  we don't care */
      filter->context =
          gst_gl_display_get_gl_context_for_thread (filter->display, NULL);
      if (!filter->context) {
        if (!gst_gl_display_create_context (filter->display,
                filter->priv->other_context, &filter->context, &error)) {
          GST_OBJECT_UNLOCK (filter->display);
          goto context_error;
        }
      }
    } while (!gst_gl_display_add_context (filter->display, filter->context));
    GST_OBJECT_UNLOCK (filter->display);
  }

  if (new_context || !filter->priv->gl_started) {
    if (filter->priv->gl_started)
      gst_gl_context_thread_add (filter->context, gst_gl_base_filter_gl_stop,
          filter);

    {
      GstGLAPI current_gl_api = gst_gl_context_get_gl_api (filter->context);
      if ((current_gl_api & filter_class->supported_gl_api) == 0)
        goto unsupported_gl_api;
    }

    gst_gl_context_thread_add (filter->context, gst_gl_base_filter_gl_start,
        filter);

    if (!filter->priv->gl_result)
      goto error;
  }

  gst_gl_context_thread_add (filter->context,
      (GstGLContextThreadFunc) _gl_set_caps, filter);
  if (!filter->priv->gl_result)
    goto error;

  return GST_BASE_TRANSFORM_CLASS (parent_class)->decide_allocation (trans,
      query);


unsupported_gl_api:
  {
    GstGLAPI gl_api = gst_gl_context_get_gl_api (filter->context);
    gchar *gl_api_str = gst_gl_api_to_string (gl_api);
    gchar *supported_gl_api_str =
        gst_gl_api_to_string (filter_class->supported_gl_api);
    GST_ELEMENT_ERROR (filter, RESOURCE, BUSY,
        ("GL API's not compatible context: %s supported: %s", gl_api_str,
            supported_gl_api_str), (NULL));

    g_free (supported_gl_api_str);
    g_free (gl_api_str);
    return FALSE;
  }
context_error:
  {
    GST_ELEMENT_ERROR (trans, RESOURCE, NOT_FOUND, ("%s", error->message),
        (NULL));
    g_clear_error (&error);
    return FALSE;
  }
error:
  {
    GST_ELEMENT_ERROR (trans, LIBRARY, INIT,
        ("Subclass failed to initialize."), (NULL));
    return FALSE;
  }
}

static gboolean
gst_gl_base_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps,
    GstCaps * outcaps)
{
  GstGLBaseFilter *filter = GST_GL_BASE_FILTER (bt);

  gst_caps_replace (&filter->in_caps, incaps);
  gst_caps_replace (&filter->out_caps, outcaps);

  return TRUE;
}

static GstStateChangeReturn
gst_gl_base_filter_change_state (GstElement * element,
    GstStateChange transition)
{
  GstGLBaseFilter *filter = GST_GL_BASE_FILTER (element);
  GstGLBaseFilterClass *filter_class = GST_GL_BASE_FILTER_GET_CLASS (filter);
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;

  GST_DEBUG_OBJECT (filter, "changing state: %s => %s",
      gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
      gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (!gst_gl_ensure_element_data (element, &filter->display,
              &filter->priv->other_context))
        return GST_STATE_CHANGE_FAILURE;

      gst_gl_display_filter_gl_api (filter->display,
          filter_class->supported_gl_api);
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_NULL:
      if (filter->priv->other_context) {
        gst_object_unref (filter->priv->other_context);
        filter->priv->other_context = NULL;
      }

      if (filter->display) {
        gst_object_unref (filter->display);
        filter->display = NULL;
      }
      break;
    default:
      break;
  }

  return ret;
}
