/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *
 * gstfdsink.c:
 *
 * 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.
 */

/**
 * SECTION:element-fdsink
 * @see_also: #GstFdSrc
 *
 * Write data to a unix file descriptor.
 *
 * This element will synchronize on the clock before writing the data on the
 * socket. For file descriptors where this does not make sense (files, ...) the
 * #GstBaseSink:sync property can be used to disable synchronisation.
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include "../../gst/gst-i18n-lib.h"

#include <sys/types.h>

#include <sys/stat.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <fcntl.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef _MSC_VER
#undef stat
#define stat _stat
#define fstat _fstat
#define S_ISREG(m)	(((m)&S_IFREG)==S_IFREG)
#endif
#include <errno.h>
#include <string.h>

#include "gstfdsink.h"
#include "gstelements_private.h"

#ifdef G_OS_WIN32
#include <io.h>                 /* lseek, open, close, read */
#undef lseek
#define lseek _lseeki64
#undef off_t
#define off_t guint64
#endif

#ifdef __BIONIC__               /* Android */
#undef lseek
#define lseek lseek64
#undef fstat
#define fstat fstat64
#undef off_t
#define off_t guint64
#endif

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

GST_DEBUG_CATEGORY_STATIC (gst_fd_sink__debug);
#define GST_CAT_DEFAULT gst_fd_sink__debug


/* FdSink signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  ARG_0,
  ARG_FD
};

static void gst_fd_sink_uri_handler_init (gpointer g_iface,
    gpointer iface_data);

#define _do_init \
  G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, gst_fd_sink_uri_handler_init); \
  GST_DEBUG_CATEGORY_INIT (gst_fd_sink__debug, "fdsink", 0, "fdsink element");
#define gst_fd_sink_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstFdSink, gst_fd_sink, GST_TYPE_BASE_SINK, _do_init);

static void gst_fd_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_fd_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_fd_sink_dispose (GObject * obj);

static gboolean gst_fd_sink_query (GstBaseSink * bsink, GstQuery * query);
static GstFlowReturn gst_fd_sink_render (GstBaseSink * sink,
    GstBuffer * buffer);
static GstFlowReturn gst_fd_sink_render_list (GstBaseSink * bsink,
    GstBufferList * buffer_list);
static gboolean gst_fd_sink_start (GstBaseSink * basesink);
static gboolean gst_fd_sink_stop (GstBaseSink * basesink);
static gboolean gst_fd_sink_unlock (GstBaseSink * basesink);
static gboolean gst_fd_sink_unlock_stop (GstBaseSink * basesink);
static gboolean gst_fd_sink_event (GstBaseSink * sink, GstEvent * event);

static gboolean gst_fd_sink_do_seek (GstFdSink * fdsink, guint64 new_offset);

static void
gst_fd_sink_class_init (GstFdSinkClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSinkClass *gstbasesink_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);
  gstbasesink_class = GST_BASE_SINK_CLASS (klass);

  gobject_class->set_property = gst_fd_sink_set_property;
  gobject_class->get_property = gst_fd_sink_get_property;
  gobject_class->dispose = gst_fd_sink_dispose;

  gst_element_class_set_static_metadata (gstelement_class,
      "Filedescriptor Sink",
      "Sink/File",
      "Write data to a file descriptor", "Erik Walthinsen <omega@cse.ogi.edu>");
  gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);

  gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_fd_sink_render);
  gstbasesink_class->render_list = GST_DEBUG_FUNCPTR (gst_fd_sink_render_list);
  gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_fd_sink_start);
  gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_fd_sink_stop);
  gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_fd_sink_unlock);
  gstbasesink_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_fd_sink_unlock_stop);
  gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_fd_sink_event);
  gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_fd_sink_query);

  g_object_class_install_property (gobject_class, ARG_FD,
      g_param_spec_int ("fd", "fd", "An open file descriptor to write to",
          0, G_MAXINT, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
gst_fd_sink_init (GstFdSink * fdsink)
{
  fdsink->fd = 1;
  fdsink->uri = g_strdup_printf ("fd://%d", fdsink->fd);
  fdsink->bytes_written = 0;
  fdsink->current_pos = 0;

  gst_base_sink_set_sync (GST_BASE_SINK (fdsink), FALSE);
}

static void
gst_fd_sink_dispose (GObject * obj)
{
  GstFdSink *fdsink = GST_FD_SINK (obj);

  g_free (fdsink->uri);
  fdsink->uri = NULL;

  G_OBJECT_CLASS (parent_class)->dispose (obj);
}

static gboolean
gst_fd_sink_query (GstBaseSink * bsink, GstQuery * query)
{
  gboolean res = FALSE;
  GstFdSink *fdsink;

  fdsink = GST_FD_SINK (bsink);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      GstFormat format;

      gst_query_parse_position (query, &format, NULL);

      switch (format) {
        case GST_FORMAT_DEFAULT:
        case GST_FORMAT_BYTES:
          gst_query_set_position (query, GST_FORMAT_BYTES, fdsink->current_pos);
          res = TRUE;
          break;
        default:
          break;
      }
      break;
    }
    case GST_QUERY_FORMATS:
      gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES);
      res = TRUE;
      break;
    case GST_QUERY_URI:
      gst_query_set_uri (query, fdsink->uri);
      res = TRUE;
      break;
    case GST_QUERY_SEEKING:{
      GstFormat format;

      gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
      if (format == GST_FORMAT_BYTES || format == GST_FORMAT_DEFAULT) {
        gst_query_set_seeking (query, GST_FORMAT_BYTES, fdsink->seekable, 0,
            -1);
      } else {
        gst_query_set_seeking (query, format, FALSE, 0, -1);
      }
      res = TRUE;
      break;
    }
    default:
      res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
      break;

  }
  return res;
}

static GstFlowReturn
gst_fd_sink_render_buffers (GstFdSink * sink, GstBuffer ** buffers,
    guint num_buffers, guint8 * mem_nums, guint total_mems)
{
  return gst_writev_buffers (GST_OBJECT_CAST (sink), sink->fd, sink->fdset,
      buffers, num_buffers, mem_nums, total_mems, &sink->bytes_written,
      &sink->current_pos);
}

static GstFlowReturn
gst_fd_sink_render_list (GstBaseSink * bsink, GstBufferList * buffer_list)
{
  GstFlowReturn flow;
  GstBuffer **buffers;
  GstFdSink *sink;
  guint8 *mem_nums;
  guint total_mems;
  guint i, num_buffers;

  sink = GST_FD_SINK_CAST (bsink);

  num_buffers = gst_buffer_list_length (buffer_list);
  if (num_buffers == 0)
    goto no_data;

  /* extract buffers from list and count memories */
  buffers = g_newa (GstBuffer *, num_buffers);
  mem_nums = g_newa (guint8, num_buffers);
  for (i = 0, total_mems = 0; i < num_buffers; ++i) {
    buffers[i] = gst_buffer_list_get (buffer_list, i);
    mem_nums[i] = gst_buffer_n_memory (buffers[i]);
    total_mems += mem_nums[i];
  }

  flow =
      gst_fd_sink_render_buffers (sink, buffers, num_buffers, mem_nums,
      total_mems);

  return flow;

no_data:
  {
    GST_LOG_OBJECT (sink, "empty buffer list");
    return GST_FLOW_OK;
  }
}

static GstFlowReturn
gst_fd_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
{
  GstFlowReturn flow;
  GstFdSink *sink;
  guint8 n_mem;

  sink = GST_FD_SINK_CAST (bsink);

  n_mem = gst_buffer_n_memory (buffer);

  if (n_mem > 0)
    flow = gst_fd_sink_render_buffers (sink, &buffer, 1, &n_mem, n_mem);
  else
    flow = GST_FLOW_OK;

  return flow;
}

static gboolean
gst_fd_sink_check_fd (GstFdSink * fdsink, int fd, GError ** error)
{
  struct stat stat_results;
  off_t result;

  /* see that it is a valid file descriptor */
  if (fstat (fd, &stat_results) < 0)
    goto invalid;

  if (!S_ISREG (stat_results.st_mode))
    goto not_seekable;

  /* see if it is a seekable stream */
  result = lseek (fd, 0, SEEK_CUR);
  if (result == -1) {
    switch (errno) {
      case EINVAL:
      case EBADF:
        goto invalid;

      case ESPIPE:
        goto not_seekable;
    }
  } else
    GST_DEBUG_OBJECT (fdsink, "File descriptor %d is seekable", fd);

  return TRUE;

invalid:
  {
    GST_ELEMENT_ERROR (fdsink, RESOURCE, WRITE, (NULL),
        ("File descriptor %d is not valid: %s", fd, g_strerror (errno)));
    g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_REFERENCE,
        "File descriptor %d is not valid: %s", fd, g_strerror (errno));
    return FALSE;
  }
not_seekable:
  {
    GST_DEBUG_OBJECT (fdsink, "File descriptor %d is a pipe", fd);
    return TRUE;
  }
}

static gboolean
gst_fd_sink_start (GstBaseSink * basesink)
{
  GstFdSink *fdsink;
  GstPollFD fd = GST_POLL_FD_INIT;

  fdsink = GST_FD_SINK (basesink);
  if (!gst_fd_sink_check_fd (fdsink, fdsink->fd, NULL))
    return FALSE;

  if ((fdsink->fdset = gst_poll_new (TRUE)) == NULL)
    goto socket_pair;

  fd.fd = fdsink->fd;
  gst_poll_add_fd (fdsink->fdset, &fd);
  gst_poll_fd_ctl_write (fdsink->fdset, &fd, TRUE);

  fdsink->bytes_written = 0;
  fdsink->current_pos = 0;

  fdsink->seekable = gst_fd_sink_do_seek (fdsink, 0);
  GST_INFO_OBJECT (fdsink, "seeking supported: %d", fdsink->seekable);

  return TRUE;

  /* ERRORS */
socket_pair:
  {
    GST_ELEMENT_ERROR (fdsink, RESOURCE, OPEN_READ_WRITE, (NULL),
        GST_ERROR_SYSTEM);
    return FALSE;
  }
}

static gboolean
gst_fd_sink_stop (GstBaseSink * basesink)
{
  GstFdSink *fdsink = GST_FD_SINK (basesink);

  if (fdsink->fdset) {
    gst_poll_free (fdsink->fdset);
    fdsink->fdset = NULL;
  }

  return TRUE;
}

static gboolean
gst_fd_sink_unlock (GstBaseSink * basesink)
{
  GstFdSink *fdsink = GST_FD_SINK (basesink);

  GST_LOG_OBJECT (fdsink, "Flushing");
  GST_OBJECT_LOCK (fdsink);
  gst_poll_set_flushing (fdsink->fdset, TRUE);
  GST_OBJECT_UNLOCK (fdsink);

  return TRUE;
}

static gboolean
gst_fd_sink_unlock_stop (GstBaseSink * basesink)
{
  GstFdSink *fdsink = GST_FD_SINK (basesink);

  GST_LOG_OBJECT (fdsink, "No longer flushing");
  GST_OBJECT_LOCK (fdsink);
  gst_poll_set_flushing (fdsink->fdset, FALSE);
  GST_OBJECT_UNLOCK (fdsink);

  return TRUE;
}

static gboolean
gst_fd_sink_update_fd (GstFdSink * fdsink, int new_fd, GError ** error)
{
  if (new_fd < 0) {
    g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_REFERENCE,
        "File descriptor %d is not valid", new_fd);
    return FALSE;
  }

  if (!gst_fd_sink_check_fd (fdsink, new_fd, error))
    goto invalid;

  /* assign the fd */
  GST_OBJECT_LOCK (fdsink);
  if (fdsink->fdset) {
    GstPollFD fd = GST_POLL_FD_INIT;

    fd.fd = fdsink->fd;
    gst_poll_remove_fd (fdsink->fdset, &fd);

    fd.fd = new_fd;
    gst_poll_add_fd (fdsink->fdset, &fd);
    gst_poll_fd_ctl_write (fdsink->fdset, &fd, TRUE);
  }
  fdsink->fd = new_fd;
  g_free (fdsink->uri);
  fdsink->uri = g_strdup_printf ("fd://%d", fdsink->fd);

  GST_OBJECT_UNLOCK (fdsink);

  return TRUE;

invalid:
  {
    return FALSE;
  }
}

static void
gst_fd_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstFdSink *fdsink;

  fdsink = GST_FD_SINK (object);

  switch (prop_id) {
    case ARG_FD:{
      int fd;

      fd = g_value_get_int (value);
      gst_fd_sink_update_fd (fdsink, fd, NULL);
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_fd_sink_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstFdSink *fdsink;

  fdsink = GST_FD_SINK (object);

  switch (prop_id) {
    case ARG_FD:
      g_value_set_int (value, fdsink->fd);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_fd_sink_do_seek (GstFdSink * fdsink, guint64 new_offset)
{
  off_t result;

  result = lseek (fdsink->fd, new_offset, SEEK_SET);

  if (result == -1)
    goto seek_failed;

  fdsink->current_pos = new_offset;

  GST_DEBUG_OBJECT (fdsink, "File descriptor %d to seek to position "
      "%" G_GUINT64_FORMAT, fdsink->fd, fdsink->current_pos);

  return TRUE;

  /* ERRORS */
seek_failed:
  {
    GST_DEBUG_OBJECT (fdsink, "File descriptor %d failed to seek to position "
        "%" G_GUINT64_FORMAT, fdsink->fd, new_offset);
    return FALSE;
  }
}

static gboolean
gst_fd_sink_event (GstBaseSink * sink, GstEvent * event)
{
  GstEventType type;
  GstFdSink *fdsink;

  fdsink = GST_FD_SINK (sink);

  type = GST_EVENT_TYPE (event);

  switch (type) {
    case GST_EVENT_SEGMENT:
    {
      const GstSegment *segment;

      gst_event_parse_segment (event, &segment);

      if (segment->format == GST_FORMAT_BYTES) {
        /* only try to seek and fail when we are going to a different
         * position */
        if (fdsink->current_pos != segment->start) {
          /* FIXME, the seek should be performed on the pos field, start/stop are
           * just boundaries for valid bytes offsets. We should also fill the file
           * with zeroes if the new position extends the current EOF (sparse streams
           * and segment accumulation). */
          if (!gst_fd_sink_do_seek (fdsink, (guint64) segment->start))
            goto seek_failed;
        }
      } else {
        GST_DEBUG_OBJECT (fdsink,
            "Ignored SEGMENT event of format %u (%s)", (guint) segment->format,
            gst_format_get_name (segment->format));
      }
      break;
    }
    default:
      break;
  }

  return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);

seek_failed:
  {
    GST_ELEMENT_ERROR (fdsink, RESOURCE, SEEK, (NULL),
        ("Error while seeking on file descriptor %d: %s",
            fdsink->fd, g_strerror (errno)));
    gst_event_unref (event);
    return FALSE;
  }

}

/*** GSTURIHANDLER INTERFACE *************************************************/

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

static const gchar *const *
gst_fd_sink_uri_get_protocols (GType type)
{
  static const gchar *protocols[] = { "fd", NULL };

  return protocols;
}

static gchar *
gst_fd_sink_uri_get_uri (GstURIHandler * handler)
{
  GstFdSink *sink = GST_FD_SINK (handler);

  /* FIXME: make thread-safe */
  return g_strdup (sink->uri);
}

static gboolean
gst_fd_sink_uri_set_uri (GstURIHandler * handler, const gchar * uri,
    GError ** error)
{
  GstFdSink *sink = GST_FD_SINK (handler);
  gint fd;

  if (sscanf (uri, "fd://%d", &fd) != 1) {
    g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
        "File descriptor URI could not be parsed");
    return FALSE;
  }

  return gst_fd_sink_update_fd (sink, fd, error);
}

static void
gst_fd_sink_uri_handler_init (gpointer g_iface, gpointer iface_data)
{
  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;

  iface->get_type = gst_fd_sink_uri_get_type;
  iface->get_protocols = gst_fd_sink_uri_get_protocols;
  iface->get_uri = gst_fd_sink_uri_get_uri;
  iface->set_uri = gst_fd_sink_uri_set_uri;
}
