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

#include "gstglmixerbin.h"

#define GST_CAT_DEFAULT gst_gl_mixer_bin_debug
GST_DEBUG_CATEGORY (gst_gl_mixer_bin_debug);

#define DEFAULT_LATENCY        0
#define DEFAULT_START_TIME_SELECTION 0
#define DEFAULT_START_TIME           (-1)

typedef enum
{
  GST_GL_MIXER_BIN_START_TIME_SELECTION_ZERO,
  GST_GL_MIXER_BIN_START_TIME_SELECTION_FIRST,
  GST_GL_MIXER_BIN_START_TIME_SELECTION_SET
} GstGLMixerBinStartTimeSelection;

static GType
gst_gl_mixer_bin_start_time_selection_get_type (void)
{
  static GType gtype = 0;

  if (gtype == 0) {
    static const GEnumValue values[] = {
      {GST_GL_MIXER_BIN_START_TIME_SELECTION_ZERO,
          "Start at 0 running time (default)", "zero"},
      {GST_GL_MIXER_BIN_START_TIME_SELECTION_FIRST,
          "Start at first observed input running time", "first"},
      {GST_GL_MIXER_BIN_START_TIME_SELECTION_SET,
          "Set start time with start-time property", "set"},
      {0, NULL, NULL}
    };

    gtype = g_enum_register_static ("GstGLMixerBinStartTimeSelection", values);
  }
  return gtype;
}

struct input_chain
{
  GstGLMixerBin *self;
  GstGhostPad *ghost_pad;
  GstElement *upload;
  GstElement *in_convert;
  GstPad *mixer_pad;
};

static void
_free_input_chain (struct input_chain *chain)
{
  if (!chain)
    return;

  chain->ghost_pad = NULL;

  if (chain->upload) {
    gst_element_set_state (chain->upload, GST_STATE_NULL);
    gst_bin_remove (GST_BIN (chain->self), chain->upload);
    chain->upload = NULL;
  }

  if (chain->in_convert) {
    gst_element_set_state (chain->in_convert, GST_STATE_NULL);
    gst_bin_remove (GST_BIN (chain->self), chain->in_convert);
    chain->in_convert = NULL;
  }

  if (chain->mixer_pad) {
    gst_element_release_request_pad (chain->self->mixer, chain->mixer_pad);
    gst_object_unref (chain->mixer_pad);
    chain->mixer_pad = NULL;
  }

  g_free (chain);
}

struct _GstGLMixerBinPrivate
{
  gboolean running;

  GList *input_chains;
};

enum
{
  PROP_0,
  PROP_MIXER,
  PROP_LATENCY,
  PROP_START_TIME_SELECTION,
  PROP_START_TIME,
};

enum
{
  SIGNAL_0,
  SIGNAL_CREATE_ELEMENT,
  LAST_SIGNAL
};

static void gst_gl_mixer_bin_child_proxy_init (gpointer g_iface,
    gpointer iface_data);

#define GST_GL_MIXER_BIN_GET_PRIVATE(o)					\
  (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_MIXER_BIN, GstGLMixerBinPrivate))
G_DEFINE_TYPE_WITH_CODE (GstGLMixerBin, gst_gl_mixer_bin, GST_TYPE_BIN,
    G_IMPLEMENT_INTERFACE (GST_TYPE_CHILD_PROXY,
        gst_gl_mixer_bin_child_proxy_init));

static guint gst_gl_mixer_bin_signals[LAST_SIGNAL] = { 0 };

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-raw(ANY)")
    );

static void gst_gl_mixer_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_gl_mixer_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_gl_mixer_bin_dispose (GObject * object);
static void gst_gl_mixer_bin_finalize (GObject * object);

static GstPad *gst_gl_mixer_bin_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps);
static void gst_gl_mixer_bin_release_pad (GstElement * element, GstPad * pad);
static GstStateChangeReturn gst_gl_mixer_bin_change_state (GstElement *
    element, GstStateChange transition);

static void
gst_gl_mixer_bin_class_init (GstGLMixerBinClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstCaps *upload_caps;

  g_type_class_add_private (klass, sizeof (GstGLMixerBinPrivate));

  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "glmixerbin", 0,
      "opengl mixer bin");

  element_class->request_new_pad = gst_gl_mixer_bin_request_new_pad;
  element_class->release_pad = gst_gl_mixer_bin_release_pad;
  element_class->change_state = gst_gl_mixer_bin_change_state;

  gobject_class->get_property = gst_gl_mixer_bin_get_property;
  gobject_class->set_property = gst_gl_mixer_bin_set_property;
  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_gl_mixer_bin_dispose);
  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_gl_mixer_bin_finalize);

  g_object_class_install_property (gobject_class, PROP_MIXER,
      g_param_spec_object ("mixer",
          "GL mixer element",
          "The GL mixer chain to use",
          GST_TYPE_ELEMENT,
          GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE |
          G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_LATENCY,
      g_param_spec_int64 ("latency", "Buffer latency",
          "Additional latency in live mode to allow upstream "
          "to take longer to produce buffers for the current "
          "position", 0,
          (G_MAXLONG == G_MAXINT64) ? G_MAXINT64 : (G_MAXLONG * GST_SECOND - 1),
          DEFAULT_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_START_TIME_SELECTION,
      g_param_spec_enum ("start-time-selection", "Start Time Selection",
          "Decides which start time is output",
          gst_gl_mixer_bin_start_time_selection_get_type (),
          DEFAULT_START_TIME_SELECTION,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_START_TIME,
      g_param_spec_uint64 ("start-time", "Start Time",
          "Start time to use if start-time-selection=set", 0,
          G_MAXUINT64,
          DEFAULT_START_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstMixerBin::create-element:
   * @object: the #GstGLMixerBin
   *
   * Will be emitted when we need the processing element/s that this bin will use
   *
   * Returns: a new #GstElement
   */
  gst_gl_mixer_bin_signals[SIGNAL_CREATE_ELEMENT] =
      g_signal_new ("create-element", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
      GST_TYPE_ELEMENT, 0);

  gst_element_class_add_static_pad_template (element_class, &src_factory);

  upload_caps = gst_gl_upload_get_input_template_caps ();
  gst_element_class_add_pad_template (element_class,
      gst_pad_template_new ("sink_%u", GST_PAD_SINK, GST_PAD_REQUEST,
          upload_caps));
  gst_caps_unref (upload_caps);

  gst_element_class_set_metadata (element_class, "OpenGL video_mixer empty bin",
      "Bin/Filter/Effect/Video/Mixer", "OpenGL video_mixer empty bin",
      "Matthew Waters <matthew@centricular.com>");
}

static void
gst_gl_mixer_bin_init (GstGLMixerBin * self)
{
  gboolean res = TRUE;
  GstPad *pad;

  self->priv = GST_GL_MIXER_BIN_GET_PRIVATE (self);

  self->out_convert = gst_element_factory_make ("glcolorconvert", NULL);
  self->download = gst_element_factory_make ("gldownload", NULL);
  res &= gst_bin_add (GST_BIN (self), self->out_convert);
  res &= gst_bin_add (GST_BIN (self), self->download);

  res &=
      gst_element_link_pads (self->out_convert, "src", self->download, "sink");

  pad = gst_element_get_static_pad (self->download, "src");
  if (!pad) {
    res = FALSE;
  } else {
    GST_DEBUG_OBJECT (self, "setting target src pad %" GST_PTR_FORMAT, pad);
    self->srcpad = gst_ghost_pad_new ("src", pad);
    gst_element_add_pad (GST_ELEMENT_CAST (self), self->srcpad);
    gst_object_unref (pad);
  }

  if (!res)
    GST_ERROR_OBJECT (self, "failed to create output chain");
}

static void
gst_gl_mixer_bin_finalize (GObject * object)
{
  GstGLMixerBin *self = GST_GL_MIXER_BIN (object);

  if (self->mixer)
    gst_object_unref (self->mixer);

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

static void
gst_gl_mixer_bin_dispose (GObject * object)
{
  GstGLMixerBin *self = GST_GL_MIXER_BIN (object);
  GList *l = self->priv->input_chains;

  while (l) {
    struct input_chain *chain = l->data;

    if (self->mixer && chain->mixer_pad) {
      gst_element_release_request_pad (GST_ELEMENT (self->mixer),
          chain->mixer_pad);
      gst_object_unref (chain->mixer_pad);
      chain->mixer_pad = NULL;
    }

    l = l->next;
  }

  g_list_free_full (self->priv->input_chains, (GDestroyNotify) g_free);

  G_OBJECT_CLASS (gst_gl_mixer_bin_parent_class)->dispose (object);
}

static gboolean
_create_input_chain (GstGLMixerBin * self, struct input_chain *chain,
    GstPad * mixer_pad)
{
  GstGLMixerBinClass *klass = GST_GL_MIXER_BIN_GET_CLASS (self);
  GstPad *pad;
  gboolean res = TRUE;
  gchar *name;

  chain->self = self;
  chain->mixer_pad = mixer_pad;

  chain->upload = gst_element_factory_make ("glupload", NULL);
  chain->in_convert = gst_element_factory_make ("glcolorconvert", NULL);

  res &= gst_bin_add (GST_BIN (self), chain->in_convert);
  res &= gst_bin_add (GST_BIN (self), chain->upload);

  pad = gst_element_get_static_pad (chain->in_convert, "src");
  if (gst_pad_link (pad, mixer_pad) != GST_PAD_LINK_OK) {
    gst_object_unref (pad);
    return FALSE;
  }
  gst_object_unref (pad);
  res &=
      gst_element_link_pads (chain->upload, "src", chain->in_convert, "sink");

  pad = gst_element_get_static_pad (chain->upload, "sink");
  if (!pad) {
    return FALSE;
  } else {
    GST_DEBUG_OBJECT (self, "setting target sink pad %" GST_PTR_FORMAT, pad);
    name = gst_object_get_name (GST_OBJECT (mixer_pad));
    if (klass->create_input_pad) {
      chain->ghost_pad = klass->create_input_pad (self, chain->mixer_pad);
      gst_object_set_name (GST_OBJECT (chain->ghost_pad), name);
      gst_ghost_pad_set_target (chain->ghost_pad, pad);
    } else {
      chain->ghost_pad =
          GST_GHOST_PAD (gst_ghost_pad_new (GST_PAD_NAME (chain->mixer_pad),
              pad));
    }
    g_free (name);

    GST_OBJECT_LOCK (self);
    if (self->priv->running)
      gst_pad_set_active (GST_PAD (chain->ghost_pad), TRUE);
    GST_OBJECT_UNLOCK (self);

    gst_element_add_pad (GST_ELEMENT_CAST (self), GST_PAD (chain->ghost_pad));
    gst_object_unref (pad);
  }

  gst_element_sync_state_with_parent (chain->upload);
  gst_element_sync_state_with_parent (chain->in_convert);

  return TRUE;
}

static GstPadTemplate *
_find_element_pad_template (GstElement * element,
    GstPadDirection direction, GstPadPresence presence)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
  GList *templ_list = gst_element_class_get_pad_template_list (klass);
  GstPadTemplate *templ;

  /* find suitable template */
  while (templ_list) {
    templ = (GstPadTemplate *) templ_list->data;

    if (GST_PAD_TEMPLATE_DIRECTION (templ) != direction
        || GST_PAD_TEMPLATE_PRESENCE (templ) != presence) {
      templ_list = templ_list->next;
      templ = NULL;
      continue;
    }

    break;
  }

  return templ;
}

static gboolean
_connect_mixer_element (GstGLMixerBin * self)
{
  gboolean res = TRUE;

  g_return_val_if_fail (self->priv->input_chains == NULL, FALSE);

  gst_object_set_name (GST_OBJECT (self->mixer), "mixer");
  res &= gst_bin_add (GST_BIN (self), self->mixer);

  res &= gst_element_link_pads (self->mixer, "src", self->out_convert, "sink");

  if (!res)
    GST_ERROR_OBJECT (self, "Failed to link mixer element into the pipeline");

  gst_element_sync_state_with_parent (self->mixer);

  return res;
}

/*
 * @mixer: (transfer floating):
 */
static gboolean
gst_gl_mixer_bin_set_mixer (GstGLMixerBin * self, GstElement * mixer)
{
  g_return_val_if_fail (GST_IS_ELEMENT (mixer), FALSE);

  if (self->mixer) {
    gst_element_set_locked_state (self->mixer, TRUE);
    gst_bin_remove (GST_BIN (self), self->mixer);
    gst_element_set_state (self->mixer, GST_STATE_NULL);
    gst_object_unref (self->mixer);
    self->mixer = NULL;
  }
  self->mixer = mixer;

  gst_object_ref_sink (mixer);

  if (mixer && !_connect_mixer_element (self)) {
    gst_object_unref (self->mixer);
    self->mixer = NULL;
    return FALSE;
  }

  return TRUE;
}

void
gst_gl_mixer_bin_finish_init_with_element (GstGLMixerBin * self,
    GstElement * element)
{
  gst_gl_mixer_bin_set_mixer (self, element);
}

void
gst_gl_mixer_bin_finish_init (GstGLMixerBin * self)
{
  GstGLMixerBinClass *klass = GST_GL_MIXER_BIN_GET_CLASS (self);
  GstElement *element = NULL;

  if (klass->create_element)
    element = klass->create_element ();

  if (element)
    gst_gl_mixer_bin_finish_init_with_element (self, element);
}

static void
gst_gl_mixer_bin_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstGLMixerBin *self = GST_GL_MIXER_BIN (object);

  switch (prop_id) {
    case PROP_MIXER:
      g_value_set_object (value, self->mixer);
      break;
    default:
      if (self->mixer)
        g_object_get_property (G_OBJECT (self->mixer), pspec->name, value);
      break;
  }
}

static void
gst_gl_mixer_bin_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstGLMixerBin *self = GST_GL_MIXER_BIN (object);

  switch (prop_id) {
    case PROP_MIXER:
    {
      GstElement *mixer = g_value_get_object (value);
      /* FIXME: deal with replacing a mixer */
      g_return_if_fail (!self->mixer || (self->mixer == mixer));
      gst_gl_mixer_bin_set_mixer (self, mixer);
      break;
    }
    default:
      if (self->mixer)
        g_object_set_property (G_OBJECT (self->mixer), pspec->name, value);
      break;
  }
}

static GstPad *
gst_gl_mixer_bin_request_new_pad (GstElement * element, GstPadTemplate * templ,
    const gchar * req_name, const GstCaps * caps)
{
  GstGLMixerBin *self = GST_GL_MIXER_BIN (element);
  GstPadTemplate *mixer_templ;
  struct input_chain *chain;
  GstPad *mixer_pad;

  chain = g_new0 (struct input_chain, 1);

  mixer_templ = _find_element_pad_template (self->mixer,
      GST_PAD_TEMPLATE_DIRECTION (templ), GST_PAD_TEMPLATE_PRESENCE (templ));
  g_return_val_if_fail (mixer_templ, NULL);

  mixer_pad =
      gst_element_request_pad (self->mixer, mixer_templ, req_name, NULL);
  g_return_val_if_fail (mixer_pad, NULL);

  if (!_create_input_chain (self, chain, mixer_pad)) {
    gst_element_release_request_pad (self->mixer, mixer_pad);
    _free_input_chain (chain);
    return NULL;
  }

  GST_OBJECT_LOCK (element);
  self->priv->input_chains = g_list_prepend (self->priv->input_chains, chain);
  GST_OBJECT_UNLOCK (element);

  gst_child_proxy_child_added (GST_CHILD_PROXY (self),
      G_OBJECT (chain->ghost_pad), GST_OBJECT_NAME (chain->ghost_pad));

  return GST_PAD (chain->ghost_pad);
}

static void
gst_gl_mixer_bin_release_pad (GstElement * element, GstPad * pad)
{
  GstGLMixerBin *self = GST_GL_MIXER_BIN (element);
  GList *l = self->priv->input_chains;
  gboolean released = FALSE;

  GST_OBJECT_LOCK (element);
  while (l) {
    struct input_chain *chain = l->data;
    if (GST_PAD (chain->ghost_pad) == pad) {
      self->priv->input_chains =
          g_list_delete_link (self->priv->input_chains, l);
      GST_OBJECT_UNLOCK (element);

      _free_input_chain (chain);
      gst_element_remove_pad (element, pad);
      released = TRUE;
      break;
    }
    l = l->next;
  }
  if (!released)
    GST_OBJECT_UNLOCK (element);
}

static GstStateChangeReturn
gst_gl_mixer_bin_change_state (GstElement * element, GstStateChange transition)
{
  GstGLMixerBin *self = GST_GL_MIXER_BIN (element);
  GstGLMixerBinClass *klass = GST_GL_MIXER_BIN_GET_CLASS (self);
  GstStateChangeReturn ret;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      GST_OBJECT_LOCK (element);
      if (!self->mixer) {
        if (klass->create_element)
          self->mixer = klass->create_element ();

        if (!self->mixer) {
          g_signal_emit (element,
              gst_gl_mixer_bin_signals[SIGNAL_CREATE_ELEMENT], 0, &self->mixer);
          if (self->mixer && g_object_is_floating (self->mixer))
            gst_object_ref_sink (self->mixer);
        }

        if (!self->mixer) {
          GST_ERROR_OBJECT (element, "Failed to retrieve element");
          GST_OBJECT_UNLOCK (element);
          return GST_STATE_CHANGE_FAILURE;
        }
        GST_OBJECT_UNLOCK (element);
        if (!_connect_mixer_element (self))
          return GST_STATE_CHANGE_FAILURE;

        GST_OBJECT_LOCK (element);
      }
      self->priv->running = TRUE;
      GST_OBJECT_UNLOCK (element);
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_NULL:
      GST_OBJECT_LOCK (self);
      self->priv->running = FALSE;
      GST_OBJECT_UNLOCK (self);
    default:
      break;
  }

  return ret;
}

static GObject *
gst_gl_mixer_bin_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
    guint index)
{
  GstGLMixerBin *mixer = GST_GL_MIXER_BIN (child_proxy);
  GstBin *bin = GST_BIN_CAST (child_proxy);
  GObject *res = NULL;

  GST_OBJECT_LOCK (bin);
  /* XXX: not exactly thread safe with ordering */
  if (index < bin->numchildren) {
    if ((res = g_list_nth_data (bin->children, index)))
      gst_object_ref (res);
  } else {
    struct input_chain *chain;
    if ((chain =
            g_list_nth_data (mixer->priv->input_chains,
                index - bin->numchildren))) {
      res = gst_object_ref (chain->ghost_pad);
    }
  }
  GST_OBJECT_UNLOCK (bin);

  return res;
}

static guint
gst_gl_mixer_bin_child_proxy_get_children_count (GstChildProxy * child_proxy)
{
  GstGLMixerBin *mixer = GST_GL_MIXER_BIN (child_proxy);
  GstBin *bin = GST_BIN_CAST (child_proxy);
  guint num;

  GST_OBJECT_LOCK (bin);
  num = bin->numchildren + g_list_length (mixer->priv->input_chains);
  GST_OBJECT_UNLOCK (bin);

  return num;
}

static void
gst_gl_mixer_bin_child_proxy_init (gpointer g_iface, gpointer iface_data)
{
  GstChildProxyInterface *iface = g_iface;

  iface->get_children_count = gst_gl_mixer_bin_child_proxy_get_children_count;
  iface->get_child_by_index = gst_gl_mixer_bin_child_proxy_get_child_by_index;
}
