/* GStreamer
 *
 * Copyright (C) 2007 Rene Stadler <mail@renestadler.de>
 * Copyright (C) 2007 Sebastian Dröge <sebastian.droege@collabora.co.uk>
 * 
 * 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 "gstgio.h"
#include "gstgiosink.h"
#include "gstgiosrc.h"
#include "gstgiostreamsink.h"
#include "gstgiostreamsrc.h"

#include <string.h>

GST_DEBUG_CATEGORY_STATIC (gst_gio_debug);
#define GST_CAT_DEFAULT gst_gio_debug

/* @func_name: Name of the GIO function, for debugging messages.
 * @err: Error location.  *err may be NULL, but err must be non-NULL.
 * @ret: Flow return location.  May be NULL.  Is set to either #GST_FLOW_ERROR
 * or #GST_FLOW_FLUSHING.
 *
 * Returns: TRUE to indicate a handled error.  Error at given location err will
 * be freed and *err will be set to NULL.  A FALSE return indicates an unhandled
 * error: The err location is unchanged and guaranteed to be != NULL.  ret, if
 * given, is set to GST_FLOW_ERROR.
 */
gboolean
gst_gio_error (gpointer element, const gchar * func_name, GError ** err,
    GstFlowReturn * ret)
{
  gboolean handled = TRUE;

  if (ret)
    *ret = GST_FLOW_ERROR;

  if (GST_GIO_ERROR_MATCHES (*err, CANCELLED)) {
    GST_DEBUG_OBJECT (element, "blocking I/O call cancelled (%s)", func_name);
    if (ret)
      *ret = GST_FLOW_FLUSHING;
  } else if (*err != NULL) {
    handled = FALSE;
  } else {
    GST_ELEMENT_ERROR (element, LIBRARY, FAILED, (NULL),
        ("%s call failed without error set", func_name));
  }

  if (handled)
    g_clear_error (err);

  return handled;
}

GstFlowReturn
gst_gio_seek (gpointer element, GSeekable * stream, guint64 offset,
    GCancellable * cancel)
{
  gboolean success;
  GstFlowReturn ret;
  GError *err = NULL;

  GST_LOG_OBJECT (element, "seeking to offset %" G_GINT64_FORMAT, offset);

  success = g_seekable_seek (stream, offset, G_SEEK_SET, cancel, &err);

  if (success)
    ret = GST_FLOW_OK;
  else if (!gst_gio_error (element, "g_seekable_seek", &err, &ret)) {
    GST_ELEMENT_ERROR (element, RESOURCE, SEEK, (NULL),
        ("Could not seek: %s", err->message));
    g_clear_error (&err);
  }

  return ret;
}

static gpointer
_internal_get_supported_protocols (gpointer data)
{
  const gchar *const *schemes;
  gchar **our_schemes;
  guint num;
  gint i, j;

  schemes = g_vfs_get_supported_uri_schemes (g_vfs_get_default ());

  if (schemes != NULL)
    num = g_strv_length ((gchar **) schemes);
  else
    num = 0;

  if (num == 0) {
    GST_WARNING ("No GIO supported URI schemes found");
    return NULL;
  }

  our_schemes = g_new0 (gchar *, num + 1);

  /* - Filter http/https as we can't support the icy stuff with GIO.
   *   Use souphttpsrc if you need that.
   * - Filter cdda as it doesn't support musicbrainz stuff and everything
   *   else one expects from a cdda source. Use cdparanoiasrc or cdiosrc
   *   for cdda.
   */
  for (i = 0, j = 0; i < num; i++) {
    if (strcmp (schemes[i], "http") == 0 || strcmp (schemes[i], "https") == 0
        || strcmp (schemes[i], "cdda") == 0)
      continue;

    our_schemes[j] = g_strdup (schemes[i]);
    j++;
  }

  return our_schemes;
}

static gchar **
gst_gio_get_supported_protocols (void)
{
  static GOnce once = G_ONCE_INIT;

  g_once (&once, _internal_get_supported_protocols, NULL);
  return (gchar **) once.retval;
}

static GstURIType
gst_gio_uri_handler_get_type_sink (GType type)
{
  return GST_URI_SINK;
}

static GstURIType
gst_gio_uri_handler_get_type_src (GType type)
{
  return GST_URI_SRC;
}

static const gchar *const *
gst_gio_uri_handler_get_protocols (GType type)
{
  static const gchar *const *protocols = NULL;

  if (!protocols)
    protocols = (const gchar * const *) gst_gio_get_supported_protocols ();

  return protocols;
}

static gchar *
gst_gio_uri_handler_get_uri (GstURIHandler * handler)
{
  GstElement *element = GST_ELEMENT (handler);
  gchar *uri;

  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);

  g_object_get (G_OBJECT (element), "location", &uri, NULL);

  return uri;
}

static gboolean
gst_gio_uri_handler_set_uri (GstURIHandler * handler, const gchar * uri,
    GError ** error)
{
  GstElement *element = GST_ELEMENT (handler);

  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);

  if (GST_STATE (element) == GST_STATE_PLAYING ||
      GST_STATE (element) == GST_STATE_PAUSED) {
    g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_STATE,
        "Changing the 'location' property while the element is running is "
        "not supported");
    return FALSE;
  }

  g_object_set (G_OBJECT (element), "location", uri, NULL);
  return TRUE;
}

static void
gst_gio_uri_handler_init (gpointer g_iface, gpointer iface_data)
{
  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
  gboolean sink = GPOINTER_TO_INT (iface_data); /* See in do_init below. */

  if (sink)
    iface->get_type = gst_gio_uri_handler_get_type_sink;
  else
    iface->get_type = gst_gio_uri_handler_get_type_src;
  iface->get_protocols = gst_gio_uri_handler_get_protocols;
  iface->get_uri = gst_gio_uri_handler_get_uri;
  iface->set_uri = gst_gio_uri_handler_set_uri;
}

void
gst_gio_uri_handler_do_init (GType type)
{
  GInterfaceInfo uri_handler_info = {
    gst_gio_uri_handler_init,
    NULL,
    NULL
  };

  /* Store information for uri_handler_init to use for distinguishing the
   * element types.  This lets us use a single interface implementation for both
   * classes. */
  uri_handler_info.interface_data = GINT_TO_POINTER (g_type_is_a (type,
          GST_TYPE_BASE_SINK));

  g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &uri_handler_info);
}

#define GIO_GVFS_MOUNTS_DIR GIO_PREFIX \
    G_DIR_SEPARATOR_S "share" \
    G_DIR_SEPARATOR_S "gvfs" \
    G_DIR_SEPARATOR_S "mounts"

static gboolean
plugin_init (GstPlugin * plugin)
{
  gboolean ret = TRUE;

  GST_DEBUG_CATEGORY_INIT (gst_gio_debug, "gio", 0, "GIO elements");

  gst_plugin_add_dependency_simple (plugin, NULL, GIO_MODULE_DIR, NULL,
      GST_PLUGIN_DEPENDENCY_FLAG_NONE);
  gst_plugin_add_dependency_simple (plugin, NULL, GIO_GVFS_MOUNTS_DIR, NULL,
      GST_PLUGIN_DEPENDENCY_FLAG_NONE);

  /* FIXME: Rank is MARGINAL for now, should be at least SECONDARY+1 in the future
   * to replace gnomevfssink/src. For testing purposes PRIMARY+1 one makes sense
   * so it gets autoplugged and preferred over filesrc/sink. */

  ret &= gst_element_register (plugin, "giosink", GST_RANK_SECONDARY,
      GST_TYPE_GIO_SINK);

  ret &= gst_element_register (plugin, "giosrc", GST_RANK_SECONDARY,
      GST_TYPE_GIO_SRC);

  ret &= gst_element_register (plugin, "giostreamsink", GST_RANK_NONE,
      GST_TYPE_GIO_STREAM_SINK);

  ret &= gst_element_register (plugin, "giostreamsrc", GST_RANK_NONE,
      GST_TYPE_GIO_STREAM_SRC);

  return ret;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, gio,
    "GIO elements", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
    GST_PACKAGE_ORIGIN)
