/* 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_static_pad_template (gstelement_class,
      &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 (TEST_HTTP_SRC_REQUEST_HEADERS_NAME);
  }
  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, TEST_HTTP_SRC_REQUEST_HEADERS_NAME,
      GST_TYPE_STRUCTURE, src->input.request_headers, NULL);
  if (!src->input.response_headers) {
    src->input.response_headers =
        gst_structure_new_empty (TEST_HTTP_SRC_RESPONSE_HEADERS_NAME);
  }
  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, TEST_HTTP_SRC_RESPONSE_HEADERS_NAME,
      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;
}
