/* GStreamer
 *
 * Copyright (C) 2007 Rene Stadler <mail@renestadler.de>
 * Copyright (C) 2007-2009 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 "gstgiobasesink.h"

GST_DEBUG_CATEGORY_STATIC (gst_gio_base_sink_debug);
#define GST_CAT_DEFAULT gst_gio_base_sink_debug

static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

#define gst_gio_base_sink_parent_class parent_class
G_DEFINE_TYPE (GstGioBaseSink, gst_gio_base_sink, GST_TYPE_BASE_SINK);

static void gst_gio_base_sink_finalize (GObject * object);
static gboolean gst_gio_base_sink_start (GstBaseSink * base_sink);
static gboolean gst_gio_base_sink_stop (GstBaseSink * base_sink);
static gboolean gst_gio_base_sink_unlock (GstBaseSink * base_sink);
static gboolean gst_gio_base_sink_unlock_stop (GstBaseSink * base_sink);
static gboolean gst_gio_base_sink_event (GstBaseSink * base_sink,
    GstEvent * event);
static GstFlowReturn gst_gio_base_sink_render (GstBaseSink * base_sink,
    GstBuffer * buffer);
static gboolean gst_gio_base_sink_query (GstBaseSink * bsink, GstQuery * query);

static void
gst_gio_base_sink_class_init (GstGioBaseSinkClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *gstelement_class = (GstElementClass *) klass;
  GstBaseSinkClass *gstbasesink_class = (GstBaseSinkClass *) klass;

  GST_DEBUG_CATEGORY_INIT (gst_gio_base_sink_debug, "gio_base_sink", 0,
      "GIO base sink");

  gobject_class->finalize = gst_gio_base_sink_finalize;

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&sink_factory));

  gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_gio_base_sink_start);
  gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_gio_base_sink_stop);
  gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_gio_base_sink_unlock);
  gstbasesink_class->unlock_stop =
      GST_DEBUG_FUNCPTR (gst_gio_base_sink_unlock_stop);
  gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_gio_base_sink_query);
  gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_gio_base_sink_event);
  gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_gio_base_sink_render);
}

static void
gst_gio_base_sink_init (GstGioBaseSink * sink)
{
  gst_base_sink_set_sync (GST_BASE_SINK (sink), FALSE);

  sink->cancel = g_cancellable_new ();
}

static void
gst_gio_base_sink_finalize (GObject * object)
{
  GstGioBaseSink *sink = GST_GIO_BASE_SINK (object);

  if (sink->cancel) {
    g_object_unref (sink->cancel);
    sink->cancel = NULL;
  }

  if (sink->stream) {
    g_object_unref (sink->stream);
    sink->stream = NULL;
  }

  GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
}

static gboolean
gst_gio_base_sink_start (GstBaseSink * base_sink)
{
  GstGioBaseSink *sink = GST_GIO_BASE_SINK (base_sink);
  GstGioBaseSinkClass *gbsink_class = GST_GIO_BASE_SINK_GET_CLASS (sink);

  sink->position = 0;

  /* FIXME: This will likely block */
  sink->stream = gbsink_class->get_stream (sink);
  if (G_UNLIKELY (!G_IS_OUTPUT_STREAM (sink->stream))) {
    GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL),
        ("No output stream provided by subclass"));
    return FALSE;
  } else if (G_UNLIKELY (g_output_stream_is_closed (sink->stream))) {
    GST_ELEMENT_ERROR (sink, LIBRARY, FAILED, (NULL),
        ("Output stream is already closed"));
    return FALSE;
  }

  GST_DEBUG_OBJECT (sink, "started sink");

  return TRUE;
}

static gboolean
gst_gio_base_sink_stop (GstBaseSink * base_sink)
{
  GstGioBaseSink *sink = GST_GIO_BASE_SINK (base_sink);
  GstGioBaseSinkClass *klass = GST_GIO_BASE_SINK_GET_CLASS (sink);
  gboolean success;
  GError *err = NULL;

  if (klass->close_on_stop && G_IS_OUTPUT_STREAM (sink->stream)) {
    GST_DEBUG_OBJECT (sink, "closing stream");

    /* FIXME: can block but unfortunately we can't use async operations
     * here because they require a running main loop */
    success = g_output_stream_close (sink->stream, sink->cancel, &err);

    if (!success && !gst_gio_error (sink, "g_output_stream_close", &err, NULL)) {
      GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
          ("gio_output_stream_close failed: %s", err->message));
      g_clear_error (&err);
    } else if (!success) {
      GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
          ("g_output_stream_close failed"));
    } else {
      GST_DEBUG_OBJECT (sink, "g_outut_stream_close succeeded");
    }

    g_object_unref (sink->stream);
    sink->stream = NULL;
  } else {
    success = g_output_stream_flush (sink->stream, sink->cancel, &err);

    if (!success && !gst_gio_error (sink, "g_output_stream_flush", &err, NULL)) {
      GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
          ("gio_output_stream_flush failed: %s", err->message));
      g_clear_error (&err);
    } else if (!success) {
      GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
          ("g_output_stream_flush failed"));
    } else {
      GST_DEBUG_OBJECT (sink, "g_outut_stream_flush succeeded");
    }

    g_object_unref (sink->stream);
    sink->stream = NULL;
  }

  return TRUE;
}

static gboolean
gst_gio_base_sink_unlock (GstBaseSink * base_sink)
{
  GstGioBaseSink *sink = GST_GIO_BASE_SINK (base_sink);

  GST_LOG_OBJECT (sink, "triggering cancellation");

  g_cancellable_cancel (sink->cancel);

  return TRUE;
}

static gboolean
gst_gio_base_sink_unlock_stop (GstBaseSink * base_sink)
{
  GstGioBaseSink *sink = GST_GIO_BASE_SINK (base_sink);

  GST_LOG_OBJECT (sink, "resetting cancellable");

  g_object_unref (sink->cancel);
  sink->cancel = g_cancellable_new ();

  return TRUE;
}

static gboolean
gst_gio_base_sink_event (GstBaseSink * base_sink, GstEvent * event)
{
  GstGioBaseSink *sink = GST_GIO_BASE_SINK (base_sink);
  GstFlowReturn ret = GST_FLOW_OK;

  if (sink->stream == NULL)
    return TRUE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
      if (G_IS_OUTPUT_STREAM (sink->stream)) {
        const GstSegment *segment;

        gst_event_parse_segment (event, &segment);

        if (segment->format != GST_FORMAT_BYTES) {
          GST_WARNING_OBJECT (sink, "ignored SEGMENT event in %s format",
              gst_format_get_name (segment->format));
          break;
        }

        if (GST_GIO_STREAM_IS_SEEKABLE (sink->stream)) {
          ret = gst_gio_seek (sink, G_SEEKABLE (sink->stream), segment->start,
              sink->cancel);
          if (ret == GST_FLOW_OK)
            sink->position = segment->start;
        } else {
          ret = GST_FLOW_NOT_SUPPORTED;
        }
      }
      break;

    case GST_EVENT_EOS:
    case GST_EVENT_FLUSH_START:
      if (G_IS_OUTPUT_STREAM (sink->stream)) {
        gboolean success;
        GError *err = NULL;

        success = g_output_stream_flush (sink->stream, sink->cancel, &err);

        if (!success && !gst_gio_error (sink, "g_output_stream_flush", &err,
                &ret)) {
          GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
              ("flush failed: %s", err->message));
          g_clear_error (&err);
        }
      }
      break;

    default:
      break;
  }
  if (ret == GST_FLOW_OK)
    return GST_BASE_SINK_CLASS (parent_class)->event (base_sink, event);
  else {
    gst_event_unref (event);
    return FALSE;
  }
}

static GstFlowReturn
gst_gio_base_sink_render (GstBaseSink * base_sink, GstBuffer * buffer)
{
  GstGioBaseSink *sink = GST_GIO_BASE_SINK (base_sink);
  gssize written;
  GstMapInfo map;
  gboolean success;
  GError *err = NULL;

  g_return_val_if_fail (G_IS_OUTPUT_STREAM (sink->stream), GST_FLOW_ERROR);

  gst_buffer_map (buffer, &map, GST_MAP_READ);

  GST_LOG_OBJECT (sink,
      "writing %" G_GSIZE_FORMAT " bytes to offset %" G_GUINT64_FORMAT,
      map.size, sink->position);

  written =
      g_output_stream_write (sink->stream, map.data, map.size, sink->cancel,
      &err);
  gst_buffer_unmap (buffer, &map);

  success = (written >= 0);

  if (G_UNLIKELY (success && written < map.size)) {
    /* FIXME: Can this happen?  Should we handle it gracefully?  gnomevfssink
     * doesn't... */
    GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
        ("Could not write to stream: (short write, only %"
            G_GSSIZE_FORMAT " bytes of %" G_GSIZE_FORMAT " bytes written)",
            written, map.size));
    return GST_FLOW_ERROR;
  }

  if (success) {
    sink->position += written;
    return GST_FLOW_OK;

  } else {
    GstFlowReturn ret;

    if (!gst_gio_error (sink, "g_output_stream_write", &err, &ret)) {
      if (GST_GIO_ERROR_MATCHES (err, NO_SPACE)) {
        GST_ELEMENT_ERROR (sink, RESOURCE, NO_SPACE_LEFT, (NULL),
            ("Could not write to stream: %s", err->message));
      } else {
        GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
            ("Could not write to stream: %s", err->message));
      }
      g_clear_error (&err);
    }

    return ret;
  }
}

static gboolean
gst_gio_base_sink_query (GstBaseSink * bsink, GstQuery * query)
{
  GstGioBaseSink *sink = GST_GIO_BASE_SINK (bsink);
  GstFormat format;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
      gst_query_parse_position (query, &format, NULL);
      switch (format) {
        case GST_FORMAT_BYTES:
        case GST_FORMAT_DEFAULT:
          gst_query_set_position (query, format, sink->position);
          return TRUE;
        default:
          return FALSE;
      }
    case GST_QUERY_FORMATS:
      gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES);
      return TRUE;
    case GST_QUERY_URI:
      if (GST_IS_URI_HANDLER (sink)) {
        gchar *uri;

        uri = gst_uri_handler_get_uri (GST_URI_HANDLER (sink));
        gst_query_set_uri (query, uri);
        g_free (uri);
        return TRUE;
      }
      return FALSE;
    case GST_QUERY_SEEKING:
      gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
      if (format == GST_FORMAT_BYTES || format == GST_FORMAT_DEFAULT) {
        gst_query_set_seeking (query, format,
            GST_GIO_STREAM_IS_SEEKABLE (sink->stream), 0, -1);
      } else {
        gst_query_set_seeking (query, format, FALSE, 0, -1);
      }
      return TRUE;
    default:
      return GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
  }
}
