/* HTTP source element for use in tests
 *
 * 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.
 */

#include <gst/check/gstcheck.h>
#include <gst/base/gstbasesrc.h>

#include "test_http_src.h"

#ifndef GST_PACKAGE_NAME
#define GST_PACKAGE_NAME "gst-plugins-bad"
#endif

#ifndef GST_PACKAGE_ORIGIN
#define GST_PACKAGE_ORIGIN "https://developer.gnome.org/gstreamer/"
#endif

#define GST_TEST_HTTP_SRC(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TEST_HTTP_SRC, GstTestHTTPSrc))
#define GST_TEST_HTTP_SRC_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TEST_HTTP_SRC, GstTestHTTPSrcClass))
#define GST_IS_TEST_HTTP_SRC(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TEST_HTTP_SRC))
#define GST_IS_TEST_HTTP_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TEST_HTTP_SRC))
#define GST_TEST_HTTP_SRC_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TEST_HTTP_SRC, GstTestHTTPSrcClass))

#define DEFAULT_USER_AGENT  "GStreamer testhttpsrc "
#define DEFAULT_COMPRESS    FALSE
#define DEFAULT_HTTP_METHOD NULL
#define DEFAULT_KEEP_ALIVE  FALSE

enum
{
  PROP_0,
  PROP_USER_AGENT,
  PROP_EXTRA_HEADERS,
  PROP_COMPRESS,
  PROP_KEEP_ALIVE,
  PROP_METHOD,
  PROP_LAST
};

typedef enum
{
  METHOD_INVALID,
  METHOD_GET,
  METHOD_POST,
  METHOD_HEAD,
  METHOD_OPTIONS
} HttpMethod;

typedef struct _GstTestHTTPSrcMethodName
{
  const gchar *name;
  HttpMethod method;
} GstTestHTTPSrcMethodName;

static const GstTestHTTPSrcMethodName gst_test_http_src_methods[] = {
  {"GET", METHOD_GET},
  {"POST", METHOD_POST},
  {"HEAD", METHOD_HEAD},
  {"OPTIONS", METHOD_OPTIONS},
  {NULL, METHOD_INVALID}
};

typedef struct _GstTestHTTPSrc
{
  GstBaseSrc parent;

  GMutex mutex;

  GstTestHTTPSrcInput input;

  gchar *uri;                   /* the uri for which data is being requested */
  gboolean compress;
  gboolean keep_alive;
  gchar *http_method_name;
  HttpMethod http_method;
  GstStructure *extra_headers;
  gchar *user_agent;

  guint64 position;
  /* index immediately after the last byte from the segment to be retrieved */
  guint64 segment_end;

  GstEvent *http_headers_event;
  gboolean duration_changed;
} GstTestHTTPSrc;

typedef struct _GstTestHTTPSrcClass
{
  GstBaseSrcClass parent_class;
} GstTestHTTPSrcClass;

typedef struct _PluginInitContext
{
  const gchar *name;
  guint rank;
  GType type;
} PluginInitContext;

static const GstTestHTTPSrcCallbacks *gst_test_http_src_callbacks = NULL;
static gpointer gst_test_http_src_callback_user_data = NULL;
static guint gst_test_http_src_blocksize = 0;

static GstStaticPadTemplate gst_dashdemux_test_source_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static void gst_test_http_src_uri_handler_init (gpointer g_iface,
    gpointer iface_data);
static void gst_test_http_src_finalize (GObject * object);
static gboolean gst_test_http_src_is_seekable (GstBaseSrc * basesrc);
static gboolean gst_test_http_src_do_seek (GstBaseSrc * basesrc,
    GstSegment * segment);
static gboolean gst_test_http_src_start (GstBaseSrc * basesrc);
static gboolean gst_test_http_src_stop (GstBaseSrc * basesrc);
static gboolean gst_test_http_src_get_size (GstBaseSrc * basesrc,
    guint64 * size);
static GstFlowReturn gst_test_http_src_create (GstBaseSrc * basesrc,
    guint64 offset, guint length, GstBuffer ** ret);
static void gst_test_http_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_test_http_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);


#define _do_init \
  G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, gst_test_http_src_uri_handler_init);

#define gst_test_http_src_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstTestHTTPSrc, gst_test_http_src,
    GST_TYPE_BASE_SRC, _do_init);

static void
gst_test_http_src_class_init (GstTestHTTPSrcClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSrcClass *gstbasesrc_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);
  gstbasesrc_class = GST_BASE_SRC_CLASS (klass);

  gobject_class->set_property = gst_test_http_src_set_property;
  gobject_class->get_property = gst_test_http_src_get_property;
  gobject_class->finalize = gst_test_http_src_finalize;

  g_object_class_install_property (gobject_class, PROP_COMPRESS,
      g_param_spec_boolean ("compress", "Compress",
          "Allow compressed content encodings",
          DEFAULT_COMPRESS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_EXTRA_HEADERS,
      g_param_spec_boxed ("extra-headers", "Extra Headers",
          "Extra headers to append to the HTTP request",
          GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_KEEP_ALIVE,
      g_param_spec_boolean ("keep-alive", "keep-alive",
          "Use HTTP persistent connections", DEFAULT_KEEP_ALIVE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_METHOD,
      g_param_spec_string ("method", "HTTP method",
          "The HTTP method to use (GET, HEAD, OPTIONS, etc)",
          DEFAULT_HTTP_METHOD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class,
      PROP_USER_AGENT,
      g_param_spec_string ("user-agent", "User-Agent",
          "Value of the User-Agent HTTP request header field",
          DEFAULT_USER_AGENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_set_metadata (gstelement_class,
      "Test HTTP source element for unit tests",
      "Source/Network",
      "Use in unit tests", "Alex Ashley <alex.ashley@youview.com>");
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_dashdemux_test_source_template));

  gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_test_http_src_start);
  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_test_http_src_stop);
  gstbasesrc_class->is_seekable =
      GST_DEBUG_FUNCPTR (gst_test_http_src_is_seekable);
  gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_test_http_src_do_seek);
  gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_test_http_src_get_size);
  gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_test_http_src_create);

}

static void
gst_test_http_src_init (GstTestHTTPSrc * src)
{
  g_mutex_init (&src->mutex);
  src->uri = NULL;
  memset (&src->input, 0, sizeof (src->input));
  src->compress = FALSE;
  src->keep_alive = FALSE;
  src->http_method_name = NULL;
  src->http_method = METHOD_GET;
  src->user_agent = NULL;
  src->position = 0;
  src->segment_end = 0;
  src->http_headers_event = NULL;
  src->duration_changed = FALSE;
  if (gst_test_http_src_blocksize)
    gst_base_src_set_blocksize (GST_BASE_SRC (src),
        gst_test_http_src_blocksize);
}

static void
gst_test_http_src_reset_input (GstTestHTTPSrc * src)
{
  src->input.context = NULL;
  src->input.size = 0;
  src->input.status_code = 0;
  if (src->input.request_headers) {
    gst_structure_free (src->input.request_headers);
    src->input.request_headers = NULL;
  }
  if (src->input.response_headers) {
    gst_structure_free (src->input.response_headers);
    src->input.response_headers = NULL;
  }
  if (src->http_headers_event) {
    gst_event_unref (src->http_headers_event);
    src->http_headers_event = NULL;
  }
  if (src->extra_headers) {
    gst_structure_free (src->extra_headers);
    src->extra_headers = NULL;
  }
  g_free (src->http_method_name);
  src->http_method_name = NULL;
  g_free (src->user_agent);
  src->user_agent = NULL;
  src->duration_changed = FALSE;
}

static void
gst_test_http_src_finalize (GObject * object)
{
  GstTestHTTPSrc *src;

  src = GST_TEST_HTTP_SRC (object);

  g_free (src->uri);
  gst_test_http_src_reset_input (src);
  g_mutex_clear (&src->mutex);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static gboolean
gst_test_http_src_start (GstBaseSrc * basesrc)
{
  GstTestHTTPSrc *src;
  GstStructure *http_headers;

  src = GST_TEST_HTTP_SRC (basesrc);
  g_mutex_lock (&src->mutex);
  gst_test_http_src_reset_input (src);
  if (!src->uri) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (("No URL set.")),
        ("Missing location property"));
    g_mutex_unlock (&src->mutex);
    return FALSE;
  }
  if (!gst_test_http_src_callbacks) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (("Callbacks not registered.")), ("Callbacks not registered"));
    g_mutex_unlock (&src->mutex);
    return FALSE;
  }
  if (!gst_test_http_src_callbacks->src_start) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (("src_start callback not defined.")),
        ("src_start callback not registered"));
    g_mutex_unlock (&src->mutex);
    return FALSE;
  }
  if (!gst_test_http_src_callbacks->src_start (src, src->uri, &src->input,
          gst_test_http_src_callback_user_data)) {
    if (src->input.status_code == 0) {
      src->input.status_code = 404;
    }
  } else {
    if (src->input.status_code == 0) {
      src->input.status_code = 200;
    }
    src->position = 0;
    src->segment_end = src->input.size;
    gst_base_src_set_dynamic_size (basesrc, FALSE);
    basesrc->segment.duration = src->input.size;
    src->duration_changed = TRUE;
  }
  http_headers = gst_structure_new_empty ("http-headers");
  gst_structure_set (http_headers, "uri", G_TYPE_STRING, src->uri, NULL);
  if (!src->input.request_headers) {
    src->input.request_headers = gst_structure_new_empty ("request-headers");
  }
  if (!gst_structure_has_field_typed (src->input.request_headers,
          "User-Agent", G_TYPE_STRING)) {
    gst_structure_set (src->input.request_headers,
        "User-Agent", G_TYPE_STRING,
        src->user_agent ? src->user_agent : DEFAULT_USER_AGENT, NULL);
  }
  if (!gst_structure_has_field_typed (src->input.request_headers,
          "Connection", G_TYPE_STRING)) {
    gst_structure_set (src->input.request_headers,
        "Connection", G_TYPE_STRING,
        src->keep_alive ? "Keep-Alive" : "Close", NULL);
  }
  if (src->compress
      && !gst_structure_has_field_typed (src->input.request_headers,
          "Accept-Encoding", G_TYPE_STRING)) {
    gst_structure_set (src->input.request_headers, "Accept-Encoding",
        G_TYPE_STRING, "compress, gzip", NULL);
  }
  gst_structure_set (http_headers, "request-headers", GST_TYPE_STRUCTURE,
      src->input.request_headers, NULL);
  if (!src->input.response_headers) {
    src->input.response_headers = gst_structure_new_empty ("response-headers");
  }
  if (!gst_structure_has_field_typed (src->input.response_headers,
          "Connection", G_TYPE_STRING)) {
    gst_structure_set (src->input.response_headers,
        "Connection", G_TYPE_STRING,
        src->keep_alive ? "keep-alive" : "close", NULL);
  }
  if (!gst_structure_has_field_typed (src->input.response_headers,
          "Date", G_TYPE_STRING)) {
    GDateTime *now;
    gchar *date_str;

    now = g_date_time_new_now_local ();
    fail_unless (now != NULL);
    date_str = g_date_time_format (now, "%a, %e %b %Y %T %Z");
    fail_unless (date_str != NULL);
    gst_structure_set (src->input.response_headers,
        "Date", G_TYPE_STRING, date_str, NULL);
    g_free (date_str);
    g_date_time_unref (now);
  }
  gst_structure_set (http_headers, "response-headers", GST_TYPE_STRUCTURE,
      src->input.response_headers, NULL);
  if (src->http_headers_event) {
    gst_event_unref (src->http_headers_event);
  }
  src->http_headers_event =
      gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, http_headers);
  g_mutex_unlock (&src->mutex);
  return TRUE;
}

static gboolean
gst_test_http_src_stop (GstBaseSrc * basesrc)
{
  GstTestHTTPSrc *src;

  src = GST_TEST_HTTP_SRC (basesrc);
  g_mutex_lock (&src->mutex);
  src->position = 0;
  gst_test_http_src_reset_input (src);
  g_mutex_unlock (&src->mutex);
  return TRUE;
}

static gboolean
gst_test_http_src_is_seekable (GstBaseSrc * basesrc)
{
  GstTestHTTPSrc *src;
  gboolean ret;

  src = GST_TEST_HTTP_SRC (basesrc);
  g_mutex_lock (&src->mutex);
  /* if size is set, we can seek */
  ret = src->input.size > 0;
  g_mutex_unlock (&src->mutex);
  return ret;
}

static gboolean
gst_test_http_src_do_seek (GstBaseSrc * basesrc, GstSegment * segment)
{
  GstTestHTTPSrc *src = GST_TEST_HTTP_SRC (basesrc);

  GST_DEBUG ("gst_test_http_src_do_seek start = %" G_GUINT64_FORMAT,
      segment->start);

  /*
     According to RFC7233, the range is inclusive:
     The first-byte-pos value in a byte-range-spec gives the byte-offset
     of the first byte in a range.  The last-byte-pos value gives the
     byte-offset of the last byte in the range; that is, the byte
     positions specified are inclusive.  Byte offsets start at zero.
   */

  g_mutex_lock (&src->mutex);
  if (!src->uri) {
    GST_DEBUG ("attempt to seek before URI set");
    g_mutex_unlock (&src->mutex);
    return FALSE;
  }
  if (src->input.status_code >= 200 && src->input.status_code < 300) {
    if (segment->start >= src->input.size) {
      GST_DEBUG ("attempt to seek to %" G_GUINT64_FORMAT " but size is %"
          G_GUINT64_FORMAT, segment->start, src->input.size);
      g_mutex_unlock (&src->mutex);
      return FALSE;
    }
    if (segment->stop != -1 && segment->stop > src->input.size) {
      g_mutex_unlock (&src->mutex);
      return FALSE;
    }
  } else {
    GST_DEBUG ("Attempt to seek on a URL that will generate HTTP error %u",
        src->input.status_code);
  }
  src->position = segment->start;

  if (segment->stop != -1) {
    src->segment_end = segment->stop;
  } else {
    src->segment_end = src->input.size;
  }
  g_mutex_unlock (&src->mutex);
  return TRUE;
}

static gboolean
gst_test_http_src_get_size (GstBaseSrc * basesrc, guint64 * size)
{
  GstTestHTTPSrc *src;

  src = GST_TEST_HTTP_SRC (basesrc);

  g_mutex_lock (&src->mutex);
  /* if it was started, size is set */
  if (src->uri && src->input.status_code >= 200 && src->input.status_code < 300) {
    *size = src->input.size;
    g_mutex_unlock (&src->mutex);
    return TRUE;
  }
  /* cannot get the size if it wasn't started */
  g_mutex_unlock (&src->mutex);
  return FALSE;
}

static GstFlowReturn
gst_test_http_src_create (GstBaseSrc * basesrc, guint64 offset,
    guint length, GstBuffer ** retbuf)
{
  GstTestHTTPSrc *src = GST_TEST_HTTP_SRC (basesrc);
  guint bytes_read;
  GstFlowReturn ret = GST_FLOW_OK;
  guint blocksize;

  fail_unless (gst_test_http_src_callbacks != NULL);
  fail_unless (gst_test_http_src_callbacks->src_create != NULL);

  GST_OBJECT_LOCK (src);
  blocksize = basesrc->blocksize;
  GST_OBJECT_UNLOCK (src);

  g_mutex_lock (&src->mutex);
  GST_DEBUG ("gst_test_http_src_create feeding from %" G_GUINT64_FORMAT,
      src->position);
  if (src->uri == NULL) {
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
    g_mutex_unlock (&src->mutex);
    return GST_FLOW_ERROR;
  }
  if (src->input.status_code < 200 || src->input.status_code >= 300) {
    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, ("%s",
            "Generated requested error"), ("%s (%d), URL: %s, Redirect to: %s",
            "Generated requested error", src->input.status_code, src->uri,
            GST_STR_NULL (NULL)));
    g_mutex_unlock (&src->mutex);
    return GST_FLOW_ERROR;
  }
  if (src->http_method == METHOD_INVALID) {
    GST_ELEMENT_ERROR (src, RESOURCE, READ, ("%s",
            "Invalid HTTP method"), ("%s (%s), URL: %s",
            "Invalid HTTP method", src->http_method_name, src->uri));
    g_mutex_unlock (&src->mutex);
    return GST_FLOW_ERROR;
  } else if (src->http_method == METHOD_HEAD) {
    ret = GST_FLOW_EOS;
    goto http_events;
  }
  fail_unless_equals_uint64 (offset, src->position);
  bytes_read = MIN ((src->segment_end - src->position), blocksize);
  if (bytes_read == 0) {
    ret = GST_FLOW_EOS;
    goto http_events;
  }
  ret = gst_test_http_src_callbacks->src_create (src,
      offset, bytes_read, retbuf,
      src->input.context, gst_test_http_src_callback_user_data);
  if (ret != GST_FLOW_OK) {
    goto http_events;
  }

  GST_BUFFER_OFFSET (*retbuf) = src->position;
  GST_BUFFER_OFFSET_END (*retbuf) = src->position + bytes_read;

  src->position += bytes_read;
http_events:
  if (src->http_headers_event) {
    gst_pad_push_event (GST_BASE_SRC_PAD (src), src->http_headers_event);
    src->http_headers_event = NULL;
  }
  if (src->duration_changed) {
    src->duration_changed = FALSE;
    gst_element_post_message (GST_ELEMENT (src),
        gst_message_new_duration_changed (GST_OBJECT (src)));
  }

  g_mutex_unlock (&src->mutex);
  return ret;
}

static void
gst_test_http_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstTestHTTPSrc *src = GST_TEST_HTTP_SRC (object);

  switch (prop_id) {
    case PROP_USER_AGENT:
      g_free (src->user_agent);
      src->user_agent = g_value_dup_string (value);
      break;
    case PROP_EXTRA_HEADERS:{
      const GstStructure *s = gst_value_get_structure (value);
      if (src->extra_headers)
        gst_structure_free (src->extra_headers);
      src->extra_headers = s ? gst_structure_copy (s) : NULL;
      break;
    }
    case PROP_COMPRESS:
      src->compress = g_value_get_boolean (value);
      GST_DEBUG ("Set compress=%s", src->compress ? "TRUE" : "FALSE");
      break;
    case PROP_KEEP_ALIVE:
      src->keep_alive = g_value_get_boolean (value);
      break;
    case PROP_METHOD:
      g_free (src->http_method_name);
      src->http_method_name = g_value_dup_string (value);
      src->http_method = METHOD_INVALID;
      for (guint i = 0; gst_test_http_src_methods[i].name; ++i) {
        if (strcmp (gst_test_http_src_methods[i].name,
                src->http_method_name) == 0) {
          src->http_method = gst_test_http_src_methods[i].method;
          break;
        }
      }
      /* we don't cause an error for an invalid method at this point,
         as GstSoupHTTPSrc does not use the http_method_name string until
         trying to open a connection.
       */
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_test_http_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstTestHTTPSrc *src = GST_TEST_HTTP_SRC (object);

  switch (prop_id) {
    case PROP_USER_AGENT:
      g_value_set_string (value, src->user_agent);
      break;
    case PROP_EXTRA_HEADERS:
      gst_value_set_structure (value, src->extra_headers);
      break;
    case PROP_COMPRESS:
      g_value_set_boolean (value, src->compress);
      break;
    case PROP_KEEP_ALIVE:
      g_value_set_boolean (value, src->keep_alive);
      break;
    case PROP_METHOD:
      g_value_set_string (value, src->http_method_name);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_test_http_src_set_location (GstTestHTTPSrc * src,
    const gchar * uri, GError ** error)
{
  g_mutex_lock (&src->mutex);
  g_free (src->uri);
  src->uri = g_strdup (uri);
  g_mutex_unlock (&src->mutex);
  return TRUE;
}

static GstURIType
gst_test_http_src_uri_get_type (GType type)
{
  return GST_URI_SRC;
}

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

  return protocols;
}

static gchar *
gst_test_http_src_uri_get_uri (GstURIHandler * handler)
{
  GstTestHTTPSrc *src = GST_TEST_HTTP_SRC (handler);
  gchar *ret;
  g_mutex_lock (&src->mutex);
  ret = g_strdup (src->uri);
  g_mutex_unlock (&src->mutex);
  return ret;
}

static gboolean
gst_test_http_src_uri_set_uri (GstURIHandler * handler, const gchar * uri,
    GError ** err)
{
  GstTestHTTPSrc *src = GST_TEST_HTTP_SRC (handler);

  return gst_test_http_src_set_location (src, uri, err);
}

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

  iface->get_type = gst_test_http_src_uri_get_type;
  iface->get_protocols = gst_test_http_src_uri_get_protocols;
  iface->get_uri = gst_test_http_src_uri_get_uri;
  iface->set_uri = gst_test_http_src_uri_set_uri;
}

static gboolean
gst_test_http_src_plugin_init_func (GstPlugin * plugin, gpointer user_data)
{
  PluginInitContext *context = (PluginInitContext *) user_data;
  gboolean ret;

  ret =
      gst_element_register (plugin, context->name, context->rank,
      context->type);
  return ret;
}

gboolean
gst_test_http_src_register_plugin (GstRegistry * registry, const gchar * name)
{
  gboolean ret;
  PluginInitContext context;

  context.name = name;
  context.rank = GST_RANK_PRIMARY + 1;
  context.type = GST_TYPE_TEST_HTTP_SRC;
  ret = gst_plugin_register_static_full (GST_VERSION_MAJOR,     /* version */
      GST_VERSION_MINOR,        /* version */
      name,                     /* name */
      "Replaces a souphttpsrc plugin and returns predefined data.",     /* description */
      gst_test_http_src_plugin_init_func,       /* init function */
      "0.0.0",                  /* version string */
      GST_LICENSE_UNKNOWN,      /* license */
      __FILE__,                 /* source */
      GST_PACKAGE_NAME,         /* package */
      GST_PACKAGE_ORIGIN,       /* origin */
      &context                  /* user_data */
      );
  return ret;
}

void
gst_test_http_src_install_callbacks (const GstTestHTTPSrcCallbacks *
    callbacks, gpointer user_data)
{
  gst_test_http_src_callbacks = callbacks;
  gst_test_http_src_callback_user_data = user_data;
}

void
gst_test_http_src_set_default_blocksize (guint blocksize)
{
  gst_test_http_src_blocksize = blocksize;
}
