/* close the socket and associated resources
 * used both to recover from errors and go to NULL state */
static gboolean
gst_neonhttp_src_stop (GstBaseSrc * bsrc)
{
  GstNeonhttpSrc *src;

  src = GST_NEONHTTP_SRC (bsrc);

  if (src->iradio_name) {
    g_free (src->iradio_name);
    src->iradio_name = NULL;
  }

  if (src->iradio_genre) {
    g_free (src->iradio_genre);
    src->iradio_genre = NULL;
  }

  if (src->iradio_url) {
    g_free (src->iradio_url);
    src->iradio_url = NULL;
  }

  if (src->icy_caps) {
    gst_caps_unref (src->icy_caps);
    src->icy_caps = NULL;
  }

  src->eos = FALSE;
  src->content_size = -1;
  src->read_position = 0;
  src->seekable = TRUE;

  gst_neonhttp_src_close_session (src);

#ifndef GST_DISABLE_GST_DEBUG
  ne_debug_init (NULL, 0);
#endif
  ne_oom_callback (NULL);
  ne_sock_exit ();

  return TRUE;
}
/* close the socket and associated resources
 * used both to recover from errors and go to NULL state */
static gboolean
gst_neonhttp_src_stop (GstBaseSrc * bsrc)
{
    GstNeonhttpSrc *src;

    src = GST_NEONHTTP_SRC (bsrc);

    src->eos = FALSE;
    src->content_size = -1;
    src->read_position = 0;
    src->seekable = TRUE;

    gst_neonhttp_src_close_session (src);

#ifndef GST_DISABLE_GST_DEBUG
    ne_debug_init (NULL, 0);
#endif
    ne_oom_callback (NULL);
    ne_sock_exit ();

    return TRUE;
}
/* create a socket for connecting to remote server */
static gboolean
gst_neonhttp_src_start (GstBaseSrc * bsrc)
{
    GstNeonhttpSrc *src = GST_NEONHTTP_SRC (bsrc);
    const gchar *content_length;
    gint res;

#ifndef GST_DISABLE_GST_DEBUG
    if (src->neon_http_debug)
        ne_debug_init (stderr, NE_DBG_HTTP);
#endif

    ne_oom_callback (oom_callback);

    res = ne_sock_init ();
    if (res != 0)
        goto init_failed;

    res = gst_neonhttp_src_send_request_and_redirect (src,
            &src->session, &src->request, 0, src->automatic_redirect);

    if (res != NE_OK || !src->session) {
        if (res == HTTP_SOCKET_ERROR) {
            goto socket_error;
        } else if (res == HTTP_REQUEST_WRONG_PROXY) {
            goto wrong_proxy;
        } else {
            goto begin_req_failed;
        }
    }

    content_length = ne_get_response_header (src->request, "Content-Length");

    if (content_length)
        src->content_size = g_ascii_strtoull (content_length, NULL, 10);
    else
        src->content_size = -1;

    if (TRUE) {
        /* Icecast stuff */
        const gchar *str_value;
        GstTagList *tags;
        gchar *iradio_name;
        gchar *iradio_url;
        gchar *iradio_genre;
        gint icy_metaint;

        tags = gst_tag_list_new_empty ();

        str_value = ne_get_response_header (src->request, "icy-metaint");
        if (str_value) {
            if (sscanf (str_value, "%d", &icy_metaint) == 1) {
                GstCaps *icy_caps;

                icy_caps = gst_caps_new_simple ("application/x-icy",
                                                "metadata-interval", G_TYPE_INT, icy_metaint, NULL);
                gst_base_src_set_caps (GST_BASE_SRC (src), icy_caps);
            }
        }

        /* FIXME: send tags with name, genre, url */
        str_value = ne_get_response_header (src->request, "icy-name");
        if (str_value) {
            iradio_name = gst_neonhttp_src_unicodify (str_value);
            if (iradio_name) {
                gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_ORGANIZATION,
                                  iradio_name, NULL);
                g_free (iradio_name);
            }
        }
        str_value = ne_get_response_header (src->request, "icy-genre");
        if (str_value) {
            iradio_genre = gst_neonhttp_src_unicodify (str_value);
            if (iradio_genre) {
                gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_GENRE,
                                  iradio_genre, NULL);
                g_free (iradio_genre);
            }
        }
        str_value = ne_get_response_header (src->request, "icy-url");
        if (str_value) {
            iradio_url = gst_neonhttp_src_unicodify (str_value);
            if (iradio_url) {
                gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_LOCATION,
                                  iradio_url, NULL);
                g_free (iradio_url);
            }
        }
        if (!gst_tag_list_is_empty (tags)) {
            GST_DEBUG_OBJECT (src, "pushing tag list %" GST_PTR_FORMAT, tags);
            gst_pad_push_event (GST_BASE_SRC_PAD (src), gst_event_new_tag (tags));
        } else {
            gst_tag_list_unref (tags);
        }
    }

    return TRUE;

    /* ERRORS */
init_failed:
    {
        GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
                           ("ne_sock_init() failed: %d", res));
        return FALSE;
    }
socket_error:
    {
        GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
                           ("HTTP Request failed when opening socket: %d", res));
        return FALSE;
    }
wrong_proxy:
    {
        GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
                           ("Proxy Server URI is invalid - make sure that either both proxy host "
                            "and port are specified or neither."));
        return FALSE;
    }
begin_req_failed:
    {
        GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
                           ("Could not begin request: %d", res));
        return FALSE;
    }
}
/* create a socket for connecting to remote server */
static gboolean
gst_neonhttp_src_start (GstBaseSrc * bsrc)
{
  GstNeonhttpSrc *src = GST_NEONHTTP_SRC (bsrc);
  const gchar *content_length;
  gint res;

#ifndef GST_DISABLE_GST_DEBUG
  if (src->neon_http_debug)
    ne_debug_init (stderr, NE_DBG_HTTP);
#endif

  ne_oom_callback (oom_callback);

  res = ne_sock_init ();
  if (res != 0)
    goto init_failed;

  res = gst_neonhttp_src_send_request_and_redirect (src,
      &src->session, &src->request, 0, src->automatic_redirect);

  if (res != NE_OK || !src->session) {
    if (res == HTTP_SOCKET_ERROR) {
      goto socket_error;
    } else if (res == HTTP_REQUEST_WRONG_PROXY) {
      goto wrong_proxy;
    } else {
      goto begin_req_failed;
    }
  }

  content_length = ne_get_response_header (src->request, "Content-Length");

  if (content_length)
    src->content_size = g_ascii_strtoull (content_length, NULL, 10);
  else
    src->content_size = -1;

  if (src->iradio_mode) {
    /* Icecast stuff */
    const gchar *str_value;
    gint gint_value;

    str_value = ne_get_response_header (src->request, "icy-metaint");
    if (str_value) {
      if (sscanf (str_value, "%d", &gint_value) == 1) {
        if (src->icy_caps) {
          gst_caps_unref (src->icy_caps);
          src->icy_caps = NULL;
        }
        src->icy_metaint = gint_value;
        src->icy_caps = gst_caps_new_simple ("application/x-icy",
            "metadata-interval", G_TYPE_INT, src->icy_metaint, NULL);
      }
    }

    str_value = ne_get_response_header (src->request, "icy-name");
    if (str_value) {
      if (src->iradio_name) {
        g_free (src->iradio_name);
        src->iradio_name = NULL;
      }
      src->iradio_name = gst_neonhttp_src_unicodify (str_value);
    }
    str_value = ne_get_response_header (src->request, "icy-genre");
    if (str_value) {
      if (src->iradio_genre) {
        g_free (src->iradio_genre);
        src->iradio_genre = NULL;
      }
      src->iradio_genre = gst_neonhttp_src_unicodify (str_value);
    }
    str_value = ne_get_response_header (src->request, "icy-url");
    if (str_value) {
      if (src->iradio_url) {
        g_free (src->iradio_url);
        src->iradio_url = NULL;
      }
      src->iradio_url = gst_neonhttp_src_unicodify (str_value);
    }
  }

  return TRUE;

  /* ERRORS */
init_failed:
  {
    GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
        ("ne_sock_init() failed: %d", res));
    return FALSE;
  }
socket_error:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("HTTP Request failed when opening socket: %d", res));
    return FALSE;
  }
wrong_proxy:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("Proxy Server URI is invalid - make sure that either both proxy host "
            "and port are specified or neither."));
    return FALSE;
  }
begin_req_failed:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("Could not begin request: %d", res));
    return FALSE;
  }
}