/* GStreamer
 * Copyright (C) 2011 Alessandro Decina <alessandro.d@gmail.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.
 */

/**
 * SECTION:element-hlssink
 *
 * HTTP Live Streaming sink/server
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 videotestsrc is-live=true ! x264enc ! mpegtsmux ! hlssink max-files=5
 * ]|
 * </refsect2>
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gsthlssink.h"
#include <gst/pbutils/pbutils.h>
#include <gst/video/video.h>
#include <gio/gio.h>
#include <glib/gstdio.h>
#include <memory.h>


GST_DEBUG_CATEGORY_STATIC (gst_hls_sink_debug);
#define GST_CAT_DEFAULT gst_hls_sink_debug

#define DEFAULT_LOCATION "segment%05d.ts"
#define DEFAULT_PLAYLIST_LOCATION "playlist.m3u8"
#define DEFAULT_PLAYLIST_ROOT NULL
#define DEFAULT_MAX_FILES 10
#define DEFAULT_TARGET_DURATION 15
#define DEFAULT_PLAYLIST_LENGTH 5

#define GST_M3U8_PLAYLIST_VERSION 3

enum
{
  PROP_0,
  PROP_LOCATION,
  PROP_PLAYLIST_LOCATION,
  PROP_PLAYLIST_ROOT,
  PROP_MAX_FILES,
  PROP_TARGET_DURATION,
  PROP_PLAYLIST_LENGTH
};

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

#define gst_hls_sink_parent_class parent_class
G_DEFINE_TYPE (GstHlsSink, gst_hls_sink, GST_TYPE_BIN);

static void gst_hls_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * spec);
static void gst_hls_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * spec);
static void gst_hls_sink_handle_message (GstBin * bin, GstMessage * message);
static GstPadProbeReturn gst_hls_sink_ghost_event_probe (GstPad * pad,
    GstPadProbeInfo * info, gpointer data);
static GstPadProbeReturn gst_hls_sink_ghost_buffer_probe (GstPad * pad,
    GstPadProbeInfo * info, gpointer data);
static void gst_hls_sink_reset (GstHlsSink * sink);
static GstStateChangeReturn
gst_hls_sink_change_state (GstElement * element, GstStateChange trans);
static gboolean schedule_next_key_unit (GstHlsSink * sink);
static GstFlowReturn gst_hls_sink_chain_list (GstPad * pad, GstObject * parent,
    GstBufferList * list);

static void
gst_hls_sink_dispose (GObject * object)
{
  GstHlsSink *sink = GST_HLS_SINK_CAST (object);

  G_OBJECT_CLASS (parent_class)->dispose ((GObject *) sink);
}

static void
gst_hls_sink_finalize (GObject * object)
{
  GstHlsSink *sink = GST_HLS_SINK_CAST (object);

  g_free (sink->location);
  g_free (sink->playlist_location);
  g_free (sink->playlist_root);
  if (sink->playlist)
    gst_m3u8_playlist_free (sink->playlist);

  G_OBJECT_CLASS (parent_class)->finalize ((GObject *) sink);
}

static void
gst_hls_sink_class_init (GstHlsSinkClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;
  GstBinClass *bin_class;

  gobject_class = (GObjectClass *) klass;
  element_class = GST_ELEMENT_CLASS (klass);
  bin_class = GST_BIN_CLASS (klass);

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_template));

  gst_element_class_set_static_metadata (element_class,
      "HTTP Live Streaming sink", "Sink", "HTTP Live Streaming sink",
      "Alessandro Decina <alessandro.d@gmail.com>");

  element_class->change_state = GST_DEBUG_FUNCPTR (gst_hls_sink_change_state);

  bin_class->handle_message = gst_hls_sink_handle_message;

  gobject_class->dispose = gst_hls_sink_dispose;
  gobject_class->finalize = gst_hls_sink_finalize;
  gobject_class->set_property = gst_hls_sink_set_property;
  gobject_class->get_property = gst_hls_sink_get_property;

  g_object_class_install_property (gobject_class, PROP_LOCATION,
      g_param_spec_string ("location", "File Location",
          "Location of the file to write", DEFAULT_LOCATION,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_PLAYLIST_LOCATION,
      g_param_spec_string ("playlist-location", "Playlist Location",
          "Location of the playlist to write", DEFAULT_PLAYLIST_LOCATION,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_PLAYLIST_ROOT,
      g_param_spec_string ("playlist-root", "Playlist Root",
          "Location of the playlist to write", DEFAULT_PLAYLIST_ROOT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_MAX_FILES,
      g_param_spec_uint ("max-files", "Max files",
          "Maximum number of files to keep on disk. Once the maximum is reached,"
          "old files start to be deleted to make room for new ones.",
          0, G_MAXUINT, DEFAULT_MAX_FILES,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_TARGET_DURATION,
      g_param_spec_uint ("target-duration", "Target duration",
          "The target duration in seconds of a segment/file. "
          "(0 - disabled, useful for management of segment duration by the "
          "streaming server)",
          0, G_MAXUINT, DEFAULT_TARGET_DURATION,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_PLAYLIST_LENGTH,
      g_param_spec_uint ("playlist-length", "Playlist length",
          "Length of HLS playlist. To allow players to conform to section 6.3.3 "
          "of the HLS specification, this should be at least 3. If set to 0, "
          "the playlist will be infinite.",
          0, G_MAXUINT, DEFAULT_PLAYLIST_LENGTH,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
gst_hls_sink_init (GstHlsSink * sink)
{
  GstPadTemplate *templ = gst_static_pad_template_get (&sink_template);
  sink->ghostpad = gst_ghost_pad_new_no_target_from_template ("sink", templ);
  gst_object_unref (templ);
  gst_element_add_pad (GST_ELEMENT_CAST (sink), sink->ghostpad);
  gst_pad_add_probe (sink->ghostpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
      gst_hls_sink_ghost_event_probe, sink, NULL);
  gst_pad_add_probe (sink->ghostpad, GST_PAD_PROBE_TYPE_BUFFER,
      gst_hls_sink_ghost_buffer_probe, sink, NULL);
  gst_pad_set_chain_list_function (sink->ghostpad, gst_hls_sink_chain_list);

  sink->location = g_strdup (DEFAULT_LOCATION);
  sink->playlist_location = g_strdup (DEFAULT_PLAYLIST_LOCATION);
  sink->playlist_root = g_strdup (DEFAULT_PLAYLIST_ROOT);
  sink->playlist_length = DEFAULT_PLAYLIST_LENGTH;
  sink->max_files = DEFAULT_MAX_FILES;
  sink->target_duration = DEFAULT_TARGET_DURATION;

  /* haven't added a sink yet, make it is detected as a sink meanwhile */
  GST_OBJECT_FLAG_SET (sink, GST_ELEMENT_FLAG_SINK);

  gst_hls_sink_reset (sink);
}

static void
gst_hls_sink_reset (GstHlsSink * sink)
{
  sink->index = 0;
  sink->count = 0;
  sink->timeout_id = 0;
  sink->last_running_time = 0;
  sink->waiting_fku = FALSE;
  gst_event_replace (&sink->force_key_unit_event, NULL);
  gst_segment_init (&sink->segment, GST_FORMAT_UNDEFINED);

  if (sink->playlist)
    gst_m3u8_playlist_free (sink->playlist);
  sink->playlist =
      gst_m3u8_playlist_new (GST_M3U8_PLAYLIST_VERSION, sink->playlist_length,
      FALSE);
}

static gboolean
gst_hls_sink_create_elements (GstHlsSink * sink)
{
  GstPad *pad = NULL;

  GST_DEBUG_OBJECT (sink, "Creating internal elements");

  if (sink->elements_created)
    return TRUE;

  sink->multifilesink = gst_element_factory_make ("multifilesink", NULL);
  if (sink->multifilesink == NULL)
    goto missing_element;

  g_object_set (sink->multifilesink, "location", sink->location,
      "next-file", 3, "post-messages", TRUE, "max-files", sink->max_files,
      NULL);

  gst_bin_add (GST_BIN_CAST (sink), sink->multifilesink);

  pad = gst_element_get_static_pad (sink->multifilesink, "sink");
  gst_ghost_pad_set_target (GST_GHOST_PAD (sink->ghostpad), pad);
  gst_object_unref (pad);

  sink->elements_created = TRUE;
  return TRUE;

missing_element:
  gst_element_post_message (GST_ELEMENT_CAST (sink),
      gst_missing_element_message_new (GST_ELEMENT_CAST (sink),
          "multifilesink"));
  GST_ELEMENT_ERROR (sink, CORE, MISSING_PLUGIN,
      (("Missing element '%s' - check your GStreamer installation."),
          "multifilesink"), (NULL));
  return FALSE;
}

static void
gst_hls_sink_write_playlist (GstHlsSink * sink)
{
  char *playlist_content;
  GError *error = NULL;

  playlist_content = gst_m3u8_playlist_render (sink->playlist);
  if (!g_file_set_contents (sink->playlist_location,
          playlist_content, -1, &error)) {
    GST_ERROR ("Failed to write playlist: %s", error->message);
    GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
        (("Failed to write playlist '%s'."), error->message), (NULL));
    g_error_free (error);
    error = NULL;
  }
  g_free (playlist_content);

}

static void
gst_hls_sink_handle_message (GstBin * bin, GstMessage * message)
{
  GstHlsSink *sink = GST_HLS_SINK_CAST (bin);

  switch (message->type) {
    case GST_MESSAGE_ELEMENT:
    {
      const char *filename;
      GstClockTime running_time, duration;
      gboolean discont = FALSE;
      gchar *entry_location;
      const GstStructure *structure;

      structure = gst_message_get_structure (message);
      if (strcmp (gst_structure_get_name (structure), "GstMultiFileSink"))
        break;

      filename = gst_structure_get_string (structure, "filename");
      gst_structure_get_clock_time (structure, "running-time", &running_time);
      duration = running_time - sink->last_running_time;
      sink->last_running_time = running_time;

      GST_INFO_OBJECT (sink, "COUNT %d", sink->index);
      if (sink->playlist_root == NULL)
        entry_location = g_path_get_basename (filename);
      else {
        gchar *name = g_path_get_basename (filename);
        entry_location = g_build_filename (sink->playlist_root, name, NULL);
        g_free (name);
      }

      gst_m3u8_playlist_add_entry (sink->playlist, entry_location,
          NULL, duration, sink->index, discont);
      g_free (entry_location);

      gst_hls_sink_write_playlist (sink);

      /* multifilesink is starting a new file. It means that upstream sent a key
       * unit and we can schedule the next key unit now.
       */
      sink->waiting_fku = FALSE;
      schedule_next_key_unit (sink);

      /* multifilesink is an internal implementation detail. If applications
       * need a notification, we should probably do our own message */
      GST_DEBUG_OBJECT (bin, "dropping message %" GST_PTR_FORMAT, message);
      gst_message_unref (message);
      message = NULL;
      break;
    }
    case GST_MESSAGE_EOS:{
      sink->playlist->end_list = TRUE;
      gst_hls_sink_write_playlist (sink);
      break;
    }
    default:
      break;
  }

  if (message)
    GST_BIN_CLASS (parent_class)->handle_message (bin, message);
}

static GstStateChangeReturn
gst_hls_sink_change_state (GstElement * element, GstStateChange trans)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstHlsSink *sink = GST_HLS_SINK_CAST (element);

  switch (trans) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (!gst_hls_sink_create_elements (sink)) {
        return GST_STATE_CHANGE_FAILURE;
      }
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, trans);

  switch (trans) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_hls_sink_reset (sink);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      gst_hls_sink_reset (sink);
      break;
    default:
      break;
  }

  return ret;
}

static void
gst_hls_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstHlsSink *sink = GST_HLS_SINK_CAST (object);

  switch (prop_id) {
    case PROP_LOCATION:
      g_free (sink->location);
      sink->location = g_value_dup_string (value);
      if (sink->multifilesink)
        g_object_set (sink->multifilesink, "location", sink->location, NULL);
      break;
    case PROP_PLAYLIST_LOCATION:
      g_free (sink->playlist_location);
      sink->playlist_location = g_value_dup_string (value);
      break;
    case PROP_PLAYLIST_ROOT:
      g_free (sink->playlist_root);
      sink->playlist_root = g_value_dup_string (value);
      break;
    case PROP_MAX_FILES:
      sink->max_files = g_value_get_uint (value);
      if (sink->multifilesink) {
        g_object_set (sink->multifilesink, "location", sink->location,
            "next-file", 3, "post-messages", TRUE, "max-files", sink->max_files,
            NULL);
      }
      break;
    case PROP_TARGET_DURATION:
      sink->target_duration = g_value_get_uint (value);
      break;
    case PROP_PLAYLIST_LENGTH:
      sink->playlist_length = g_value_get_uint (value);
      sink->playlist->window_size = sink->playlist_length;
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_hls_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstHlsSink *sink = GST_HLS_SINK_CAST (object);

  switch (prop_id) {
    case PROP_LOCATION:
      g_value_set_string (value, sink->location);
      break;
    case PROP_PLAYLIST_LOCATION:
      g_value_set_string (value, sink->playlist_location);
      break;
    case PROP_PLAYLIST_ROOT:
      g_value_set_string (value, sink->playlist_root);
      break;
    case PROP_MAX_FILES:
      g_value_set_uint (value, sink->max_files);
      break;
    case PROP_TARGET_DURATION:
      g_value_set_uint (value, sink->target_duration);
      break;
    case PROP_PLAYLIST_LENGTH:
      g_value_set_uint (value, sink->playlist_length);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstPadProbeReturn
gst_hls_sink_ghost_event_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer data)
{
  GstHlsSink *sink = GST_HLS_SINK_CAST (data);
  GstEvent *event = gst_pad_probe_info_get_event (info);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      gst_event_copy_segment (event, &sink->segment);
      break;
    }
    case GST_EVENT_FLUSH_STOP:
      gst_segment_init (&sink->segment, GST_FORMAT_UNDEFINED);
      break;
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    {
      GstClockTime timestamp;
      GstClockTime running_time, stream_time;
      gboolean all_headers;
      guint count;

      if (!gst_video_event_is_force_key_unit (event))
        break;

      gst_event_replace (&sink->force_key_unit_event, event);
      gst_video_event_parse_downstream_force_key_unit (event,
          &timestamp, &stream_time, &running_time, &all_headers, &count);
      GST_INFO_OBJECT (sink, "setting index %d", count);
      sink->index = count;
      break;
    }
    default:
      break;
  }

  return GST_PAD_PROBE_OK;
}

static gboolean
schedule_next_key_unit (GstHlsSink * sink)
{
  gboolean res = TRUE;
  GstClockTime running_time;
  GstPad *sinkpad = gst_element_get_static_pad (GST_ELEMENT (sink), "sink");

  if (sink->target_duration == 0)
    /* target-duration == 0 means that the app schedules key units itself */
    goto out;

  running_time = sink->last_running_time + sink->target_duration * GST_SECOND;
  GST_INFO_OBJECT (sink, "sending upstream force-key-unit, index %d "
      "now %" GST_TIME_FORMAT " target %" GST_TIME_FORMAT,
      sink->index + 1, GST_TIME_ARGS (sink->last_running_time),
      GST_TIME_ARGS (running_time));

  if (!(res = gst_pad_push_event (sinkpad,
              gst_video_event_new_upstream_force_key_unit (running_time,
                  TRUE, sink->index + 1)))) {
    GST_ERROR_OBJECT (sink, "Failed to push upstream force key unit event");
  }

out:
  /* mark as waiting for a fku event if the app schedules them or if we just
   * successfully scheduled one
   */
  sink->waiting_fku = res;
  gst_object_unref (sinkpad);
  return res;
}

static void
gst_hls_sink_check_schedule_next_key_unit (GstHlsSink * sink, GstBuffer * buf)
{
  GstClockTime timestamp;

  timestamp = GST_BUFFER_TIMESTAMP (buf);
  if (!GST_CLOCK_TIME_IS_VALID (timestamp))
    return;

  sink->last_running_time = gst_segment_to_running_time (&sink->segment,
      GST_FORMAT_TIME, timestamp);
  schedule_next_key_unit (sink);
}

static GstPadProbeReturn
gst_hls_sink_ghost_buffer_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer data)
{
  GstHlsSink *sink = GST_HLS_SINK_CAST (data);
  GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);

  if (sink->target_duration == 0 || sink->waiting_fku)
    return GST_PAD_PROBE_OK;

  gst_hls_sink_check_schedule_next_key_unit (sink, buffer);
  return GST_PAD_PROBE_OK;
}

static GstFlowReturn
gst_hls_sink_chain_list (GstPad * pad, GstObject * parent, GstBufferList * list)
{
  guint i, len;
  GstBuffer *buffer;
  GstFlowReturn ret;
  GstHlsSink *sink = GST_HLS_SINK_CAST (parent);

  if (sink->target_duration == 0 || sink->waiting_fku)
    return gst_proxy_pad_chain_list_default (pad, parent, list);

  GST_DEBUG_OBJECT (pad, "chaining each group in list as a merged buffer");

  len = gst_buffer_list_length (list);

  ret = GST_FLOW_OK;
  for (i = 0; i < len; i++) {
    buffer = gst_buffer_list_get (list, i);

    if (!sink->waiting_fku)
      gst_hls_sink_check_schedule_next_key_unit (sink, buffer);

    ret = gst_pad_chain (pad, gst_buffer_ref (buffer));
    if (ret != GST_FLOW_OK)
      break;
  }
  gst_buffer_list_unref (list);

  return ret;
}

gboolean
gst_hls_sink_plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (gst_hls_sink_debug, "hlssink", 0, "HlsSink");
  return gst_element_register (plugin, "hlssink", GST_RANK_NONE,
      gst_hls_sink_get_type ());
}
