/* GStreamer
 *
 * Copyright (C) <2015> Centricular Ltd
 *  @author: Edward Hervey <edward@centricular.com>
 *  @author: Jan Schmidt <jan@centricular.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.
 */

#if 0
/* Not needed for now - we're including gstdecodebin3-parse.c into gstdecodebin3.c */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <glib.h>
#include <glib-object.h>
#include <glib/gprintf.h>
#include <gst/gst.h>
#include <gst/pbutils/pbutils.h>

#include "gstplayback.h"
#endif

/* Streams that come from demuxers (input/upstream) */
/* FIXME : All this is hardcoded. Switch to tree of chains */
struct _DecodebinInputStream
{
  GstDecodebin3 *dbin;
  GstStream *pending_stream;    /* Extra ref */
  GstStream *active_stream;

  DecodebinInput *input;

  GstPad *srcpad;               /* From demuxer */

  /* id of the pad event probe */
  gulong output_event_probe_id;

  /* id of the buffer blocking probe on the input (demuxer src) pad */
  gulong input_buffer_probe_id;

  /* Whether we saw an EOS on input. This should be treated accordingly
   * when the stream is no longer used */
  gboolean saw_eos;
  /* TRUE if the EOS being pushed is only for draining and does not represent
   * the full media EOS */
  gboolean drain_eos;
};

static void parsebin_pad_added_cb (GstElement * demux, GstPad * pad,
    DecodebinInput * input);
static void parsebin_pad_removed_cb (GstElement * demux, GstPad * pad,
    DecodebinInput * input);

static gboolean
pending_pads_are_eos (DecodebinInput * input)
{
  GList *tmp;

  for (tmp = input->pending_pads; tmp; tmp = tmp->next) {
    PendingPad *ppad = (PendingPad *) tmp->data;
    if (ppad->saw_eos == FALSE)
      return FALSE;
  }

  return TRUE;
}

static gboolean
all_inputs_are_eos (GstDecodebin3 * dbin)
{
  GList *tmp;
  /* First check input streams */
  for (tmp = dbin->input_streams; tmp; tmp = tmp->next) {
    DecodebinInputStream *input = (DecodebinInputStream *) tmp->data;
    if (input->saw_eos == FALSE)
      return FALSE;
  }

  /* Check pending pads */
  if (!pending_pads_are_eos (dbin->main_input))
    return FALSE;
  for (tmp = dbin->other_inputs; tmp; tmp = tmp->next)
    if (!pending_pads_are_eos ((DecodebinInput *) tmp->data))
      return FALSE;

  GST_DEBUG_OBJECT (dbin, "All streams are EOS");
  return TRUE;
}

static void
check_all_streams_for_eos (GstDecodebin3 * dbin)
{
  GList *tmp;

  if (!all_inputs_are_eos (dbin))
    return;

  /* We know all streams are EOS, properly clean up everything */
  for (tmp = dbin->input_streams; tmp; tmp = tmp->next) {
    DecodebinInputStream *input = (DecodebinInputStream *) tmp->data;
    GstPad *peer = gst_pad_get_peer (input->srcpad);

    /* Send EOS and then remove elements */
    if (peer) {
      gst_pad_send_event (peer, gst_event_new_eos ());
      gst_object_unref (peer);
    }
    GST_FIXME_OBJECT (input->srcpad, "Remove input stream");
  }
}

/* Get the intersection of parser caps and available (sorted) decoders */
static GstCaps *
get_parser_caps_filter (GstDecodebin3 * dbin, GstCaps * caps)
{
  GList *tmp;
  GstCaps *filter_caps = gst_caps_new_empty ();

  g_mutex_lock (&dbin->factories_lock);
  gst_decode_bin_update_factories_list (dbin);
  for (tmp = dbin->decoder_factories; tmp; tmp = tmp->next) {
    GstElementFactory *factory = (GstElementFactory *) tmp->data;
    GstCaps *tcaps, *intersection;
    const GList *tmps;

    GST_LOG ("Trying factory %s",
        gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
    for (tmps = gst_element_factory_get_static_pad_templates (factory); tmps;
        tmps = tmps->next) {
      GstStaticPadTemplate *st = (GstStaticPadTemplate *) tmps->data;
      if (st->direction != GST_PAD_SINK || st->presence != GST_PAD_ALWAYS)
        continue;
      tcaps = gst_static_pad_template_get_caps (st);
      intersection =
          gst_caps_intersect_full (tcaps, caps, GST_CAPS_INTERSECT_FIRST);
      filter_caps = gst_caps_merge (filter_caps, intersection);
      gst_caps_unref (tcaps);
    }
  }
  g_mutex_unlock (&dbin->factories_lock);
  GST_DEBUG_OBJECT (dbin, "Got filter caps %" GST_PTR_FORMAT, filter_caps);
  return filter_caps;
}

static gboolean
check_parser_caps_filter (GstDecodebin3 * dbin, GstCaps * caps)
{
  GList *tmp;
  gboolean res = FALSE;

  g_mutex_lock (&dbin->factories_lock);
  gst_decode_bin_update_factories_list (dbin);
  for (tmp = dbin->decoder_factories; tmp; tmp = tmp->next) {
    GstElementFactory *factory = (GstElementFactory *) tmp->data;
    GstCaps *tcaps;
    const GList *tmps;

    GST_LOG ("Trying factory %s",
        gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
    for (tmps = gst_element_factory_get_static_pad_templates (factory); tmps;
        tmps = tmps->next) {
      GstStaticPadTemplate *st = (GstStaticPadTemplate *) tmps->data;
      if (st->direction != GST_PAD_SINK || st->presence != GST_PAD_ALWAYS)
        continue;
      tcaps = gst_static_pad_template_get_caps (st);
      if (gst_caps_can_intersect (tcaps, caps)) {
        res = TRUE;
        gst_caps_unref (tcaps);
        goto beach;
      }
      gst_caps_unref (tcaps);
    }
  }
beach:
  g_mutex_unlock (&dbin->factories_lock);
  GST_DEBUG_OBJECT (dbin, "Can intersect : %d", res);
  return res;
}

/* Probe on the output of a parser chain (the last
 * src pad) */
static GstPadProbeReturn
parse_chain_output_probe (GstPad * pad, GstPadProbeInfo * info,
    DecodebinInputStream * input)
{
  GstPadProbeReturn ret = GST_PAD_PROBE_OK;

  if (GST_IS_EVENT (GST_PAD_PROBE_INFO_DATA (info))) {
    GstEvent *ev = GST_PAD_PROBE_INFO_EVENT (info);

    GST_DEBUG_OBJECT (pad, "Got event %s", GST_EVENT_TYPE_NAME (ev));
    switch (GST_EVENT_TYPE (ev)) {
      case GST_EVENT_STREAM_START:
      {
        GstStream *stream = NULL;
        guint group_id = G_MAXUINT32;
        gst_event_parse_group_id (ev, &group_id);
        GST_DEBUG_OBJECT (pad, "Got stream-start, group_id:%d, input %p",
            group_id, input->input);
        if (set_input_group_id (input->input, &group_id)) {
          ev = gst_event_make_writable (ev);
          gst_event_set_group_id (ev, group_id);
          GST_PAD_PROBE_INFO_DATA (info) = ev;
        }
        input->saw_eos = FALSE;

        gst_event_parse_stream (ev, &stream);
        /* FIXME : Would we ever end up with a stream already set on the input ?? */
        if (stream) {
          if (input->active_stream != stream) {
            MultiQueueSlot *slot;
            if (input->active_stream)
              gst_object_unref (input->active_stream);
            input->active_stream = stream;
            /* We have the beginning of a stream, get a multiqueue slot and link to it */
            g_mutex_lock (&input->dbin->selection_lock);
            slot = get_slot_for_input (input->dbin, input);
            link_input_to_slot (input, slot);
            g_mutex_unlock (&input->dbin->selection_lock);
          } else
            gst_object_unref (stream);
        }
      }
        break;
      case GST_EVENT_CAPS:
      {
        GstCaps *caps = NULL;
        gst_event_parse_caps (ev, &caps);
        GST_DEBUG_OBJECT (pad, "caps %" GST_PTR_FORMAT, caps);
        if (caps && input->active_stream)
          gst_stream_set_caps (input->active_stream, caps);
      }
        break;
      case GST_EVENT_EOS:
        /* FIXME : Make sure this makes sense ... */
        if (TRUE) {
          GST_DEBUG_OBJECT (pad, "real input pad, marking as EOS");
          input->saw_eos = TRUE;
          check_all_streams_for_eos (input->dbin);
          ret = GST_PAD_PROBE_DROP;
        } else {
          MultiQueueSlot *slot;

          g_mutex_lock (&input->dbin->selection_lock);
          slot = get_slot_for_input (input->dbin, input);
          g_mutex_unlock (&input->dbin->selection_lock);

          slot->drain_eos = input->drain_eos;

          if (input->drain_eos) {
            GST_DEBUG_OBJECT (pad,
                "Got EOS at end of input stream (drain_eos:%d) Dropping.",
                input->drain_eos);
            ret = GST_PAD_PROBE_DROP;
          } else {
            GST_DEBUG_OBJECT (pad,
                "Got EOS at end of input stream (drain_eos:%d) Passing.",
                input->drain_eos);
          }
        }
        break;
      default:
        break;
    }
  } else if (GST_IS_QUERY (GST_PAD_PROBE_INFO_DATA (info))) {
    GstQuery *q = GST_PAD_PROBE_INFO_QUERY (info);
    GST_DEBUG_OBJECT (pad, "Seeing query %s", GST_QUERY_TYPE_NAME (q));
    /* If we have a parser, we want to reply to the caps query */
    /* FIXME: Set a flag when the input stream is created for
     * streams where we shouldn't reply to these queries */
    if (GST_QUERY_TYPE (q) == GST_QUERY_CAPS
        && (info->type & GST_PAD_PROBE_TYPE_PULL)) {
      GstCaps *filter = NULL;
      GstCaps *allowed;
      gst_query_parse_caps (q, &filter);
      allowed = get_parser_caps_filter (input->dbin, filter);
      GST_DEBUG_OBJECT (pad,
          "Intercepting caps query, setting %" GST_PTR_FORMAT, allowed);
      gst_query_set_caps_result (q, allowed);
      gst_caps_unref (allowed);
      ret = GST_PAD_PROBE_HANDLED;
    } else if (GST_QUERY_TYPE (q) == GST_QUERY_ACCEPT_CAPS) {
      GstCaps *prop = NULL;
      gst_query_parse_accept_caps (q, &prop);
      /* Fast check against target caps */
      if (gst_caps_can_intersect (prop, input->dbin->caps))
        gst_query_set_accept_caps_result (q, TRUE);
      else {
        gboolean accepted = check_parser_caps_filter (input->dbin, prop);
        /* check against caps filter */
        gst_query_set_accept_caps_result (q, accepted);
        GST_DEBUG_OBJECT (pad, "ACCEPT_CAPS query, returning %d", accepted);
      }
      ret = GST_PAD_PROBE_HANDLED;
    }
  }

  return ret;
}

static DecodebinInputStream *
create_input_stream (GstDecodebin3 * dbin, GstStream * stream, GstPad * pad,
    DecodebinInput * input)
{
  DecodebinInputStream *res = g_new0 (DecodebinInputStream, 1);

  GST_DEBUG_OBJECT (pad, "Creating input stream for stream %p %s (input:%p)",
      stream, gst_stream_get_stream_id (stream), input);

  res->dbin = dbin;
  res->input = input;
  res->pending_stream = gst_object_ref (stream);
  res->srcpad = pad;

  /* Put probe on output source pad (for detecting EOS/STREAM_START) */
  res->output_event_probe_id =
      gst_pad_add_probe (pad,
      GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM,
      (GstPadProbeCallback) parse_chain_output_probe, res, NULL);

  /* Add to list of current input streams */
  dbin->input_streams = g_list_append (dbin->input_streams, res);
  GST_DEBUG_OBJECT (pad, "Done creating input stream");

  return res;
}

static void
remove_input_stream (GstDecodebin3 * dbin, DecodebinInputStream * stream)
{
  MultiQueueSlot *slot;

  GST_DEBUG_OBJECT (dbin, "Removing input stream %p (%s)", stream,
      stream->active_stream ? gst_stream_get_stream_id (stream->active_stream) :
      "<NONE>");

  /* Unlink from slot */
  if (stream->srcpad) {
    GstPad *peer;
    peer = gst_pad_get_peer (stream->srcpad);
    if (peer) {
      gst_pad_unlink (stream->srcpad, peer);
      gst_object_unref (peer);
    }
  }

  g_mutex_lock (&dbin->selection_lock);
  slot = get_slot_for_input (dbin, stream);
  g_mutex_unlock (&dbin->selection_lock);
  if (slot) {
    slot->pending_stream = NULL;
    slot->input = NULL;
    GST_DEBUG_OBJECT (dbin, "slot %p cleared", slot);
  }

  if (stream->active_stream)
    gst_object_unref (stream->active_stream);
  if (stream->pending_stream)
    gst_object_unref (stream->pending_stream);

  dbin->input_streams = g_list_remove (dbin->input_streams, stream);

  g_free (stream);
}


/* FIXME : HACK, REMOVE, USE INPUT CHAINS */
static GstPadProbeReturn
parsebin_buffer_probe (GstPad * pad, GstPadProbeInfo * info,
    DecodebinInput * input)
{
  GstDecodebin3 *dbin = input->dbin;
  GList *tmp, *unused_slot = NULL;

  GST_FIXME_OBJECT (dbin, "Need a lock !");

  GST_DEBUG_OBJECT (pad, "Got a buffer ! UNBLOCK !");

  /* Any data out the demuxer means it's not creating pads
   * any more right now */

  /* 1. Re-use existing streams if/when possible */
  GST_FIXME_OBJECT (dbin, "Re-use existing input streams if/when possible");

  /* 2. Remove unused streams (push EOS) */
  GST_DEBUG_OBJECT (dbin, "Removing unused streams");
  tmp = dbin->input_streams;
  while (tmp != NULL) {
    DecodebinInputStream *input_stream = (DecodebinInputStream *) tmp->data;
    GList *next = tmp->next;

    GST_DEBUG_OBJECT (dbin, "Checking input stream %p", input_stream);
    if (input_stream->input_buffer_probe_id) {
      GST_DEBUG_OBJECT (dbin,
          "Removing pad block on input %p pad %" GST_PTR_FORMAT, input_stream,
          input_stream->srcpad);
      gst_pad_remove_probe (input_stream->srcpad,
          input_stream->input_buffer_probe_id);
    }
    input_stream->input_buffer_probe_id = 0;

    if (input_stream->saw_eos) {
      remove_input_stream (dbin, input_stream);
      tmp = dbin->input_streams;
    } else
      tmp = next;
  }

  GST_DEBUG_OBJECT (dbin, "Creating new streams (if needed)");
  /* 3. Create new streams */
  for (tmp = input->pending_pads; tmp; tmp = tmp->next) {
    GstStream *stream;
    PendingPad *ppad = (PendingPad *) tmp->data;

    stream = gst_pad_get_stream (ppad->pad);
    if (stream == NULL) {
      GST_ERROR_OBJECT (dbin, "No stream for pad ????");
    } else {
      MultiQueueSlot *slot;
      DecodebinInputStream *input_stream;
      /* The remaining pads in pending_pads are the ones that require a new
       * input stream */
      input_stream = create_input_stream (dbin, stream, ppad->pad, ppad->input);
      /* See if we can link it straight away */
      input_stream->active_stream = stream;

      g_mutex_lock (&dbin->selection_lock);
      slot = get_slot_for_input (dbin, input_stream);
      link_input_to_slot (input_stream, slot);
      g_mutex_unlock (&dbin->selection_lock);

      /* Remove the buffer and event probe */
      gst_pad_remove_probe (ppad->pad, ppad->buffer_probe);
      gst_pad_remove_probe (ppad->pad, ppad->event_probe);
      g_free (ppad);
    }
  }

  g_list_free (input->pending_pads);
  input->pending_pads = NULL;

  /* Weed out unused multiqueue slots */
  g_mutex_lock (&dbin->selection_lock);
  for (tmp = dbin->slots; tmp; tmp = tmp->next) {
    MultiQueueSlot *slot = (MultiQueueSlot *) tmp->data;
    GST_LOG_OBJECT (dbin, "Slot %d input:%p drain_eos:%d",
        slot->id, slot->input, slot->drain_eos);
    if (slot->input == NULL) {
      unused_slot =
          g_list_append (unused_slot, gst_object_ref (slot->sink_pad));
    }
  }
  g_mutex_unlock (&dbin->selection_lock);

  for (tmp = unused_slot; tmp; tmp = tmp->next) {
    GstPad *sink_pad = (GstPad *) tmp->data;
    GST_DEBUG_OBJECT (sink_pad, "Sending EOS to unused slot");
    gst_pad_send_event (sink_pad, gst_event_new_eos ());
  }

  if (unused_slot)
    g_list_free_full (unused_slot, (GDestroyNotify) gst_object_unref);

  return GST_PAD_PROBE_OK;
}

static GstPadProbeReturn
parsebin_pending_event_probe (GstPad * pad, GstPadProbeInfo * info,
    PendingPad * ppad)
{
  GstDecodebin3 *dbin = ppad->dbin;
  /* We drop all events by default */
  GstPadProbeReturn ret = GST_PAD_PROBE_DROP;
  GstEvent *ev = GST_PAD_PROBE_INFO_EVENT (info);

  GST_DEBUG_OBJECT (pad, "Got event %p %s", ev, GST_EVENT_TYPE_NAME (ev));
  switch (GST_EVENT_TYPE (ev)) {
    case GST_EVENT_EOS:
    {
      GST_DEBUG_OBJECT (pad, "Pending pad marked as EOS, removing");
      ppad->input->pending_pads =
          g_list_remove (ppad->input->pending_pads, ppad);
      gst_pad_remove_probe (ppad->pad, ppad->buffer_probe);
      gst_pad_remove_probe (ppad->pad, ppad->event_probe);
      g_free (ppad);

      check_all_streams_for_eos (dbin);
    }
      break;
    default:
      break;
  }

  return ret;
}

static void
parsebin_pad_added_cb (GstElement * demux, GstPad * pad, DecodebinInput * input)
{
  GstDecodebin3 *dbin = input->dbin;
  PendingPad *ppad;
  GList *tmp;

  GST_DEBUG_OBJECT (dbin, "New pad %s:%s (input:%p)", GST_DEBUG_PAD_NAME (pad),
      input);

  ppad = g_new0 (PendingPad, 1);
  ppad->dbin = dbin;
  ppad->input = input;
  ppad->pad = pad;

  ppad->event_probe =
      gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
      (GstPadProbeCallback) parsebin_pending_event_probe, ppad, NULL);
  ppad->buffer_probe =
      gst_pad_add_probe (pad,
      GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
      (GstPadProbeCallback) parsebin_buffer_probe, input, NULL);

  input->pending_pads = g_list_append (input->pending_pads, ppad);

  /* FIXME : ONLY DO FOR THIS PARSEBIN/INPUT ! */
  /* Check if all existing input streams have a buffer probe set */
  for (tmp = dbin->input_streams; tmp; tmp = tmp->next) {
    DecodebinInputStream *input_stream = (DecodebinInputStream *) tmp->data;
    if (input_stream->input_buffer_probe_id == 0) {
      GST_DEBUG_OBJECT (input_stream->srcpad, "Adding blocking buffer probe");
      input_stream->input_buffer_probe_id =
          gst_pad_add_probe (input_stream->srcpad,
          GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
          (GstPadProbeCallback) parsebin_buffer_probe, input_stream->input,
          NULL);
    }
  }
}

static void
parsebin_pad_removed_cb (GstElement * demux, GstPad * pad, DecodebinInput * inp)
{
  GstDecodebin3 *dbin = inp->dbin;
  DecodebinInputStream *input = NULL;
  GList *tmp;
  GST_DEBUG_OBJECT (pad, "removed");

  for (tmp = dbin->input_streams; tmp; tmp = tmp->next) {
    DecodebinInputStream *cand = (DecodebinInputStream *) tmp->data;
    if (cand->srcpad == pad)
      input = cand;
  }
  /* If there are no pending pads, this means we will definitely not need this
   * stream anymore */
  if (input) {
    GST_DEBUG_OBJECT (pad, "stream %p", input);
    if (inp->pending_pads == NULL) {
      GST_DEBUG_OBJECT (pad, "Remove input stream %p", input);
      remove_input_stream (dbin, input);
    } else {
      input->srcpad = NULL;
      if (input->input_buffer_probe_id)
        gst_pad_remove_probe (pad, input->input_buffer_probe_id);
      input->input_buffer_probe_id = 0;
    }
  }
}
