/* A generic test engine for elements based upon GstAdaptiveDemux 
 *
 * Copyright (c) <2015> YouView TV Ltd
 *
 * 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.
 */

#ifndef __GST_ADAPTIVE_DEMUX_TEST_ENGINE_H__
#define __GST_ADAPTIVE_DEMUX_TEST_ENGINE_H__

#include <gst/gst.h>
#include <gst/app/gstappsink.h>
#include "test_http_src.h"

G_BEGIN_DECLS

typedef struct _GstAdaptiveDemuxTestEngine GstAdaptiveDemuxTestEngine;

typedef struct _GstAdaptiveDemuxTestOutputStream {
  /* the GstAppSink element getting the data for this stream */
  GstAppSink *appsink;
  GstPad *pad;
  /* the internal pad of adaptivedemux element used to send data to the GstAppSink element */
  GstPad *internal_pad;
  gulong internal_pad_probe;
  /* current segment start offset */
  guint64 segment_start;
  /* the size received so far on this segment */
  guint64 segment_received_size;
  /* the total size received so far on this stream, excluding current segment */
  guint64 total_received_size;
} GstAdaptiveDemuxTestOutputStream;

/* GstAdaptiveDemuxTestCallbacks: contains various callbacks that can
 * be registered by a test. Not all callbacks needs to be configured
 * by a test. A callback that is not required by a test must be set
 * to NULL.
 */
typedef struct _GstAdaptiveDemuxTestCallbacks
{
  /**
   * pre_test: called before starting the pipeline
   * @engine: #GstAdaptiveDemuxTestEngine
   * @user_data: the user_data passed to gst_adaptive_demux_test_run()
   */
  void (*pre_test) (GstAdaptiveDemuxTestEngine *engine, gpointer user_data);
  
  /**
   * post_test: called after stopping the pipeline.
   * @engine: #GstAdaptiveDemuxTestEngine
   * @user_data: the user_data passed to gst_adaptive_demux_test_run()
   */
  void (*post_test) (GstAdaptiveDemuxTestEngine *engine, gpointer user_data);

  /**
   * appsink_received_data: called each time AppSink receives data
   * @engine: #GstAdaptiveDemuxTestEngine
   * @stream: #GstAdaptiveDemuxTestOutputStream
   * @buffer: the #GstBuffer that was recevied by #GstAppSink
   * @user_data: the user_data passed to gst_adaptive_demux_test_run()
   * Returns: #TRUE to continue processing, #FALSE to cause EOS
   *
   * Can be used by a test to perform additional operations (eg validate
   * output data)
   */
  gboolean (*appsink_received_data) (GstAdaptiveDemuxTestEngine *engine,
      GstAdaptiveDemuxTestOutputStream * stream,
      GstBuffer * buffer, gpointer user_data);

  /**
   * appsink_eos: called each time AppSink receives eos
   * @engine: #GstAdaptiveDemuxTestEngine
   * @stream: #GstAdaptiveDemuxTestOutputStream
   * @user_data: the user_data passed to gst_adaptive_demux_test_run()
   *
   * Can be used by a test to perform additional operations (eg validate
   * output data)
   */
  void (*appsink_eos) (GstAdaptiveDemuxTestEngine *engine,
      GstAdaptiveDemuxTestOutputStream * stream, gpointer user_data);

  /**
   * appsink_event: called when an event is received by appsink
   * @engine: #GstAdaptiveDemuxTestEngine
   * @stream: #GstAdaptiveDemuxTestOutputStream
   * @event: the #GstEvent that was pushed in the demuxer pad
   * @user_data: the user_data passed to gst_adaptive_demux_test_run()
   *
   * Can be used by a test to do some checks on the events
   */
  void (*appsink_event) (GstAdaptiveDemuxTestEngine *engine,
      GstAdaptiveDemuxTestOutputStream * stream,
      GstEvent * event, gpointer user_data);

  /**
   * demux_pad_added: called each time the demux creates a new pad
   * @engine: #GstAdaptiveDemuxTestEngine
   * @stream: the #GstAdaptiveDemuxTestOutputStream that has been created
   * @user_data: the user_data passed to gst_adaptive_demux_test_run()
   */
  void (*demux_pad_added) (GstAdaptiveDemuxTestEngine * engine,
      GstAdaptiveDemuxTestOutputStream * stream, gpointer user_data);

  /**
   * demux_pad_removed: called each time the demux removes a pad
   * @engine: #GstAdaptiveDemuxTestEngine
   * @stream: the #GstAdaptiveDemuxTestOutputStream that will no longer
   * be used
   * @user_data: the user_data passed to gst_adaptive_demux_test_run()
   */
  void (*demux_pad_removed) (GstAdaptiveDemuxTestEngine * engine,
      GstAdaptiveDemuxTestOutputStream * stream, gpointer user_data);

  /**
   * demux_sent_data: called each time the demux sends data to AppSink
   * @engine: #GstAdaptiveDemuxTestEngine
   * @stream: #GstAdaptiveDemuxTestOutputStream
   * @buffer: the #GstBuffer that was sent by demux
   * @user_data: the user_data passed to gst_adaptive_demux_test_run()
   */
  gboolean (*demux_sent_data) (GstAdaptiveDemuxTestEngine *engine,
      GstAdaptiveDemuxTestOutputStream * stream,
      GstBuffer * buffer, gpointer user_data);

  /**
   * demux_sent_event: called each time the demux sends event to AppSink
   * @engine: #GstAdaptiveDemuxTestEngine
   * @stream: #GstAdaptiveDemuxTestOutputStream
   * @event: the #GstEvent that was sent by demux
   * @user_data: the user_data passed to gst_adaptive_demux_test_run()
   */
  gboolean (*demux_sent_event) (GstAdaptiveDemuxTestEngine *engine,
      GstAdaptiveDemuxTestOutputStream * stream,
      GstEvent * event, gpointer user_data);

  /**
   * bus_error_message: called if an error is posted to the bus
   * @engine: #GstAdaptiveDemuxTestEngine
   * @msg: the #GstMessage that contains the error
   * @user_data: the user_data passed to gst_adaptive_demux_test_run()
   *
   * The callback can decide if this error is expected, or to fail
   * the test
   */
  void (*bus_error_message)(GstAdaptiveDemuxTestEngine *engine,
      GstMessage * msg, gpointer user_data);
} GstAdaptiveDemuxTestCallbacks;

/* structure containing all data used by a test
 * Any callback defined by a test will receive this as first parameter
 */
struct _GstAdaptiveDemuxTestEngine
{
  GstElement *pipeline;
  GstClock *clock;
  GstElement *demux;
  GstElement *manifest_source;
  GMainLoop *loop;
  GPtrArray *output_streams; /* GPtrArray<GstAdaptiveDemuxTestOutputStream> */
  /* mutex to lock accesses to this structure when data is shared 
   * between threads */
  GMutex lock;
};

/**
 * gst_adaptive_demux_test_run:
 * @element_name: The name of the demux element (e.g. "dashdemux")
 * @manifest_uri: The URI of the manifest to load
 * @callbacks: The callbacks to use while the test is in operating
 * @user_data: Opaque pointer that is passed to every callback
 *
 * Creates a pipeline with the specified demux element in it,
 * connect a testhttpsrc element to this demux element and
 * request manifest_uri. When the demux element adds a new
 * pad, the engine will create an AppSink element and attach
 * it to this pad. 
 *
 * Information about these pads is collected in 
 * GstAdaptiveDemuxTestEngine::output_streams
 */
void gst_adaptive_demux_test_run (const gchar * element_name,
    const gchar * manifest_uri,
    const GstAdaptiveDemuxTestCallbacks * callbacks,
    gpointer user_data);

G_END_DECLS
#endif /* __GST_ADAPTIVE_DEMUX_TEST_ENGINE_H__ */
