/* GStreamer
 *
 * Copyright (C) 2015 Centricular Ltd
 *  @author: Edward Hervey <edward@centricular.com>
 *  @author: Jan Schmidt <jan@centricular.com>
 *
 * gststreams.c: GstStream and GstStreamCollection object and methods
 *
 * 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.
 *
 * MT safe.
 */

/**
 * SECTION:gststreams
 * @short_description: Base class for stream objects
 *
 * A #GstStream is a high-level object defining a stream of data which is, or
 * can be, present in a #GstPipeline.
 *
 * It is defined by a unique identifier, a "Stream ID". A #GstStream does not
 * automatically imply the stream is present within a pipeline or element.
 *
 * Any element that can introduce new streams in a pipeline should create the
 * appropriate #GstStream object, and can convey that object via the
 * %GST_EVENT_STREAM_START event and/or the #GstStreamCollection.
 *
 * Elements that do not modify the nature of the stream can add extra information
 * on it (such as enrich the #GstCaps, or #GstTagList). This is typically done
 * by parsing elements.
 *
 * Since: 1.10
 */

#include "gst_private.h"

#include "gstenumtypes.h"
#include "gstevent.h"
#include "gststreams.h"

GST_DEBUG_CATEGORY_STATIC (streams_debug);
#define GST_CAT_DEFAULT streams_debug

#define GST_STREAM_GET_PRIVATE(obj)  \
   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_STREAM, GstStreamPrivate))

struct _GstStreamPrivate
{
  GstStreamFlags flags;
  GstStreamType type;
  GstTagList *tags;
  GstCaps *caps;
};

/* stream signals and properties */
enum
{
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_STREAM_ID,
  PROP_STREAM_FLAGS,
  PROP_STREAM_TYPE,
  PROP_TAGS,
  PROP_CAPS,
  PROP_LAST
};

static GParamSpec *gst_stream_pspecs[PROP_LAST] = { 0 };

#if 0
static guint gst_stream_signals[LAST_SIGNAL] = { 0 };
#endif

static void gst_stream_finalize (GObject * object);

static void gst_stream_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_stream_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

#define _do_init				\
{ \
  GST_DEBUG_CATEGORY_INIT (streams_debug, "streams", GST_DEBUG_BOLD, \
      "debugging info for the stream and stream collection objects"); \
  \
}

#define gst_stream_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstStream, gst_stream, GST_TYPE_OBJECT, _do_init);

static void
gst_stream_class_init (GstStreamClass * klass)
{
  GObjectClass *gobject_class;

  gobject_class = (GObjectClass *) klass;

  g_type_class_add_private (klass, sizeof (GstStreamPrivate));

  gobject_class->set_property = gst_stream_set_property;
  gobject_class->get_property = gst_stream_get_property;

  /**
   * GstStream:stream-id:
   *
   * The unique identifier of the #GstStream. Can only be set at construction
   * time.
   */
  g_object_class_install_property (gobject_class, PROP_STREAM_ID,
      g_param_spec_string ("stream-id", "Stream ID",
          "The stream ID of the stream",
          NULL,
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));

  /**
   * GstStream:flags:
   *
   * The #GstStreamFlags of the #GstStream. Can only be set at construction time.
   **/
  gst_stream_pspecs[PROP_STREAM_FLAGS] =
      g_param_spec_flags ("stream-flags", "Stream Flags", "The stream flags",
      GST_TYPE_STREAM_FLAGS, GST_STREAM_FLAG_NONE,
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
  g_object_class_install_property (gobject_class, PROP_STREAM_FLAGS,
      gst_stream_pspecs[PROP_STREAM_FLAGS]);

  /**
   * GstStream:stream-type:
   *
   * The #GstStreamType of the #GstStream. Can only be set at construction time.
   **/
  gst_stream_pspecs[PROP_STREAM_TYPE] =
      g_param_spec_flags ("stream-type", "Stream Type", "The type of stream",
      GST_TYPE_STREAM_TYPE, GST_STREAM_TYPE_UNKNOWN,
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
  g_object_class_install_property (gobject_class, PROP_STREAM_TYPE,
      gst_stream_pspecs[PROP_STREAM_TYPE]);

  /**
   * GstStream:caps:
   *
   * The #GstCaps of the #GstStream.
   **/
  gst_stream_pspecs[PROP_CAPS] =
      g_param_spec_boxed ("caps", "Caps", "The caps of the stream",
      GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
  g_object_class_install_property (gobject_class, PROP_CAPS,
      gst_stream_pspecs[PROP_CAPS]);

  /**
   * GstStream:tags:
   *
   * The #GstTagList of the #GstStream.
   **/
  gst_stream_pspecs[PROP_TAGS] =
      g_param_spec_boxed ("tags", "Tags", "The tags of the stream",
      GST_TYPE_TAG_LIST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
  g_object_class_install_property (gobject_class, PROP_TAGS,
      gst_stream_pspecs[PROP_TAGS]);

  gobject_class->finalize = gst_stream_finalize;
}

static void
gst_stream_init (GstStream * stream)
{
  stream->priv = GST_STREAM_GET_PRIVATE (stream);
  stream->priv->type = GST_STREAM_TYPE_UNKNOWN;
}

static void
gst_stream_finalize (GObject * object)
{
  GstStream *stream = GST_STREAM_CAST (object);

  gst_mini_object_replace ((GstMiniObject **) & stream->priv->tags,
      (GstMiniObject *) NULL);
  gst_caps_replace (&stream->priv->caps, NULL);
  g_free ((gchar *) stream->stream_id);

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

/**
 * gst_stream_new:
 * @stream_id: (allow-none): the id for the new stream. If %NULL,
 * a new one will be automatically generated
 * @caps: (allow-none) (transfer none): the #GstCaps of the stream
 * @type: the #GstStreamType of the stream
 * @flags: the #GstStreamFlags of the stream
 *
 * Create a new #GstStream for the given @stream_id, @caps, @type
 * and @flags
 *
 * Returns: The new #GstStream
 *
 * Since: 1.10
 */
GstStream *
gst_stream_new (const gchar * stream_id, GstCaps * caps, GstStreamType type,
    GstStreamFlags flags)
{
  return g_object_new (GST_TYPE_STREAM, "stream-id", stream_id, "caps", caps,
      "stream-type", type, "stream-flags", flags, NULL);
}

static void
gst_stream_set_stream_id (GstStream * stream, const gchar * stream_id)
{
  GST_OBJECT_LOCK (stream);
  g_assert (stream->stream_id == NULL);
  if (stream_id)
    stream->stream_id = g_strdup (stream_id);
  else {
    /* Create a randoom stream_id if NULL */
    GST_FIXME_OBJECT (stream, "Creating random stream-id, consider "
        "implementing a deterministic way of creating a stream-id");
    stream->stream_id =
        g_strdup_printf ("%08x%08x%08x%08x", g_random_int (), g_random_int (),
        g_random_int (), g_random_int ());
  }

  GST_OBJECT_UNLOCK (stream);
}

/**
 * gst_stream_get_stream_id:
 * @stream: a #GstStream
 *
 * Returns the stream ID of @stream.
 *
 * Returns: (transfer none) (nullable): the stream ID of @stream. Only valid
 * during the lifetime of @stream.
 *
 * Since: 1.10
 */
const gchar *
gst_stream_get_stream_id (GstStream * stream)
{
  return stream->stream_id;
}

/**
 * gst_stream_set_stream_flags:
 * @stream: a #GstStream
 * @flags: the flags to set on @stream
 *
 * Set the @flags for the @stream.
 *
 * Since: 1.10
 */
void
gst_stream_set_stream_flags (GstStream * stream, GstStreamFlags flags)
{
  GST_OBJECT_LOCK (stream);
  stream->priv->flags = flags;
  GST_OBJECT_UNLOCK (stream);

  g_object_notify_by_pspec (G_OBJECT (stream),
      gst_stream_pspecs[PROP_STREAM_FLAGS]);
}

/**
 * gst_stream_get_stream_flags:
 * @stream: a #GstStream
 *
 * Retrieve the current stream flags for @stream
 *
 * Returns: The #GstStreamFlags for @stream
 *
 * Since: 1.10
 */
GstStreamFlags
gst_stream_get_stream_flags (GstStream * stream)
{
  GstStreamFlags res;

  GST_OBJECT_LOCK (stream);
  res = stream->priv->flags;
  GST_OBJECT_UNLOCK (stream);

  return res;
}

/**
 * gst_stream_set_stream_type:
 * @stream: a #GstStream
 * @stream_type: the type to set on @stream
 *
 * Set the stream type of @stream
 *
 * Since: 1.10
 */
void
gst_stream_set_stream_type (GstStream * stream, GstStreamType stream_type)
{
  GST_OBJECT_LOCK (stream);
  stream->priv->type = stream_type;
  GST_OBJECT_UNLOCK (stream);

  g_object_notify_by_pspec (G_OBJECT (stream),
      gst_stream_pspecs[PROP_STREAM_TYPE]);
}

/**
 * gst_stream_get_stream_type:
 * @stream: a #GstStream
 *
 * Retrieve the stream type for @stream
 *
 * Returns: The #GstStreamType for @stream
 *
 * Since: 1.10
 */
GstStreamType
gst_stream_get_stream_type (GstStream * stream)
{
  GstStreamType res;

  GST_OBJECT_LOCK (stream);
  res = stream->priv->type;
  GST_OBJECT_UNLOCK (stream);

  return res;
}

/**
 * gst_stream_set_tags:
 * @stream: a #GstStream
 * @tags: (transfer none) (allow-none): a #GstTagList
 *
 * Set the tags for the #GstStream
 *
 * Since: 1.10
 */
void
gst_stream_set_tags (GstStream * stream, GstTagList * tags)
{
  gboolean notify = FALSE;

  GST_OBJECT_LOCK (stream);
  if (stream->priv->tags == NULL || tags == NULL
      || !gst_tag_list_is_equal (stream->priv->tags, tags)) {
    gst_mini_object_replace ((GstMiniObject **) & stream->priv->tags,
        (GstMiniObject *) tags);
    notify = TRUE;
  }
  GST_OBJECT_UNLOCK (stream);

  if (notify)
    g_object_notify_by_pspec (G_OBJECT (stream), gst_stream_pspecs[PROP_TAGS]);
}

/**
 * gst_stream_get_tags:
 * @stream: a #GstStream
 *
 * Retrieve the tags for @stream, if any
 *
 * Returns: (transfer full) (nullable): The #GstTagList for @stream
 *
 * Since: 1.10
 */
GstTagList *
gst_stream_get_tags (GstStream * stream)
{
  GstTagList *res = NULL;

  GST_OBJECT_LOCK (stream);
  if (stream->priv->tags)
    res = gst_tag_list_ref (stream->priv->tags);
  GST_OBJECT_UNLOCK (stream);

  return res;
}

/**
 * gst_stream_set_caps:
 * @stream: a #GstStream
 * @caps: (transfer none) (allow-none): a #GstCaps
 *
 * Set the caps for the #GstStream
 *
 * Since: 1.10
 */
void
gst_stream_set_caps (GstStream * stream, GstCaps * caps)
{
  gboolean notify = FALSE;

  GST_OBJECT_LOCK (stream);
  if (stream->priv->caps == NULL || (caps
          && !gst_caps_is_equal (stream->priv->caps, caps))) {
    gst_caps_replace (&stream->priv->caps, caps);
    notify = TRUE;
  }
  GST_OBJECT_UNLOCK (stream);

  if (notify)
    g_object_notify_by_pspec (G_OBJECT (stream), gst_stream_pspecs[PROP_CAPS]);
}


/**
 * gst_stream_get_caps:
 * @stream: a #GstStream
 *
 * Retrieve the caps for @stream, if any
 *
 * Returns: (transfer full) (nullable): The #GstCaps for @stream
 *
 * Since: 1.10
 */
GstCaps *
gst_stream_get_caps (GstStream * stream)
{
  GstCaps *res = NULL;

  GST_OBJECT_LOCK (stream);
  if (stream->priv->caps)
    res = gst_caps_ref (stream->priv->caps);
  GST_OBJECT_UNLOCK (stream);

  return res;
}

static void
gst_stream_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstStream *stream;

  stream = GST_STREAM_CAST (object);

  switch (prop_id) {
    case PROP_STREAM_ID:
      gst_stream_set_stream_id (stream, g_value_get_string (value));
      break;
    case PROP_STREAM_FLAGS:
      GST_OBJECT_LOCK (stream);
      stream->priv->flags = g_value_get_flags (value);
      GST_OBJECT_UNLOCK (stream);
      break;
    case PROP_STREAM_TYPE:
      GST_OBJECT_LOCK (stream);
      stream->priv->type = g_value_get_flags (value);
      GST_OBJECT_UNLOCK (stream);
      break;
    case PROP_TAGS:
      GST_OBJECT_LOCK (stream);
      gst_mini_object_replace ((GstMiniObject **) & stream->priv->tags,
          (GstMiniObject *) g_value_get_boxed (value));
      GST_OBJECT_UNLOCK (stream);
      break;
    case PROP_CAPS:
      GST_OBJECT_LOCK (stream);
      gst_mini_object_replace ((GstMiniObject **) & stream->priv->caps,
          (GstMiniObject *) g_value_get_boxed (value));
      GST_OBJECT_UNLOCK (stream);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_stream_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstStream *stream;

  stream = GST_STREAM_CAST (object);

  switch (prop_id) {
    case PROP_STREAM_ID:
      g_value_set_string (value, gst_stream_get_stream_id (stream));
      break;
    case PROP_STREAM_FLAGS:
      g_value_set_flags (value, gst_stream_get_stream_flags (stream));
      break;
    case PROP_STREAM_TYPE:
      g_value_set_flags (value, gst_stream_get_stream_type (stream));
      break;
    case PROP_TAGS:
      g_value_take_boxed (value, gst_stream_get_tags (stream));
      break;
    case PROP_CAPS:
      g_value_take_boxed (value, gst_stream_get_caps (stream));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/**
 * gst_stream_type_get_name:
 * @stype: a #GstStreamType
 *
 * Get a descriptive string for a given #GstStreamType
 *
 * Returns: A string describing the stream type
 *
 * Since: 1.10
 */
const gchar *
gst_stream_type_get_name (GstStreamType stype)
{
  /* FIXME : Make this more flexible */
  switch (stype) {
    case GST_STREAM_TYPE_UNKNOWN:
      return "unknown";
    case GST_STREAM_TYPE_AUDIO:
      return "audio";
    case GST_STREAM_TYPE_VIDEO:
      return "video";
    case GST_STREAM_TYPE_CONTAINER:
      return "container";
    case GST_STREAM_TYPE_TEXT:
      return "text";
    default:
      return NULL;
  }

  return NULL;
}
