/* GStreamer Windows network source
 * Copyright (C) 2008 Ole André Vadla Ravnås <ole.andre.ravnas@tandberg.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.
 */

/**
 * SECTION:element-wininetsrc
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 -v wininetsrc location="http://71.83.57.210:9000" ! application/x-icy,metadata-interval=0 ! icydemux ! mad ! audioconvert ! directsoundsink
 * ]| receive mp3 audio over http and play it back.
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "gstwininetsrc.h"

#include <string.h>

#define DEFAULT_LOCATION "http://localhost/"
#define DEFAULT_POLL_MODE FALSE
#define DEFAULT_IRADIO_MODE TRUE

enum
{
  PROP_0,
  PROP_LOCATION,
  PROP_POLL_MODE,
  PROP_IRADIO_MODE
};

GST_DEBUG_CATEGORY_STATIC (gst_win_inet_src_debug);
#define GST_CAT_DEFAULT gst_win_inet_src_debug

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

static void gst_win_inet_src_init_interfaces (GType type);
static void gst_win_inet_src_uri_handler_init (gpointer g_iface,
    gpointer iface_data);

static void gst_win_inet_src_dispose (GObject * object);
static void gst_win_inet_src_finalize (GObject * object);
static void gst_win_inet_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_win_inet_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);

static gboolean gst_win_inet_src_start (GstBaseSrc * basesrc);
static gboolean gst_win_inet_src_stop (GstBaseSrc * basesrc);

static GstFlowReturn gst_win_inet_src_create (GstPushSrc * pushsrc,
    GstBuffer ** buffer);

static void gst_win_inet_src_reset (GstWinInetSrc * self);

GST_BOILERPLATE_FULL (GstWinInetSrc, gst_win_inet_src, GstPushSrc,
    GST_TYPE_PUSH_SRC, gst_win_inet_src_init_interfaces);

static void
gst_win_inet_src_base_init (gpointer gclass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);

  gst_element_class_add_static_pad_template (element_class, &src_template);

  gst_element_class_set_static_metadata (element_class,
      "Windows Network Source", "Source/Network",
      "Receive data as a client over the network via HTTP or FTP",
      "Ole André Vadla Ravnås <ole.andre.ravnas@tandberg.com>");
}

static void
gst_win_inet_src_class_init (GstWinInetSrcClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
  GstPushSrcClass *gstpushsrc_class = GST_PUSH_SRC_CLASS (klass);

  gobject_class->dispose = gst_win_inet_src_dispose;
  gobject_class->finalize = gst_win_inet_src_finalize;
  gobject_class->get_property = gst_win_inet_src_get_property;
  gobject_class->set_property = gst_win_inet_src_set_property;

  gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_win_inet_src_start);
  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_win_inet_src_stop);
  gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_win_inet_src_create);

  g_object_class_install_property (gobject_class,
      PROP_LOCATION, g_param_spec_string ("location", "Location",
          "Location to read from", DEFAULT_LOCATION, G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
      PROP_POLL_MODE, g_param_spec_boolean ("poll-mode", "poll-mode",
          "Enable poll mode (keep re-issuing request)",
          DEFAULT_POLL_MODE, G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
      PROP_IRADIO_MODE, g_param_spec_boolean ("iradio-mode", "iradio-mode",
          "Enable Internet radio mode "
          "(extraction of shoutcast/icecast metadata)",
          DEFAULT_IRADIO_MODE, G_PARAM_READWRITE));
}

static void
gst_win_inet_src_init_interfaces (GType type)
{
  static const GInterfaceInfo uri_handler_info = {
    gst_win_inet_src_uri_handler_init,
    NULL,
    NULL
  };

  g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &uri_handler_info);

  GST_DEBUG_CATEGORY_INIT (gst_win_inet_src_debug, "wininetsrc",
      0, "Wininet source");
}

static void
gst_win_inet_src_init (GstWinInetSrc * self, GstWinInetSrcClass * gclass)
{
  self->location = g_strdup (DEFAULT_LOCATION);
  self->poll_mode = DEFAULT_POLL_MODE;
  self->iradio_mode = DEFAULT_IRADIO_MODE;

  self->inet = NULL;
  self->url = NULL;
  self->cur_offset = 0;
  self->icy_caps = NULL;
}

static void
gst_win_inet_src_dispose (GObject * object)
{
  GstWinInetSrc *self = GST_WIN_INET_SRC (object);

  gst_win_inet_src_reset (self);

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

static void
gst_win_inet_src_finalize (GObject * object)
{
  GstWinInetSrc *self = GST_WIN_INET_SRC (object);

  g_free (self->location);

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

static void
gst_win_inet_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstWinInetSrc *self = GST_WIN_INET_SRC (object);

  switch (prop_id) {
    case PROP_LOCATION:
      g_value_set_string (value, self->location);
      break;

    case PROP_POLL_MODE:
      g_value_set_boolean (value, self->poll_mode);
      break;

    case PROP_IRADIO_MODE:
      g_value_set_boolean (value, self->iradio_mode);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_win_inet_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstWinInetSrc *self = GST_WIN_INET_SRC (object);

  switch (prop_id) {
    case PROP_LOCATION:
      if (GST_STATE (self) == GST_STATE_PLAYING ||
          GST_STATE (self) == GST_STATE_PAUSED) {
        GST_WARNING_OBJECT (self, "element must be in stopped or paused state "
            "in order to change location");
        break;
      }

      g_free (self->location);
      self->location = g_value_dup_string (value);
      break;

    case PROP_POLL_MODE:
      self->poll_mode = g_value_get_boolean (value);
      break;

    case PROP_IRADIO_MODE:
      self->iradio_mode = g_value_get_boolean (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_win_inet_src_reset (GstWinInetSrc * self)
{
  if (self->url != NULL) {
    InternetCloseHandle (self->url);
    self->url = NULL;
  }

  if (self->inet != NULL) {
    InternetCloseHandle (self->inet);
    self->inet = NULL;
  }

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

  self->cur_offset = 0;
}

static gboolean
gst_win_inet_src_get_header_value_as_int (GstWinInetSrc * self,
    const gchar * header_name, gint * header_value, gboolean log_failure)
{
  gchar buf[16] = { 0, };
  DWORD buf_size = sizeof (buf);
  gint *value = (gint *) buf;

  strcpy (buf, header_name);

  if (!HttpQueryInfo (self->url, HTTP_QUERY_CUSTOM | HTTP_QUERY_FLAG_NUMBER,
          buf, &buf_size, NULL)) {
    if (log_failure) {
      DWORD error_code = GetLastError ();
      const gchar *error_str = "unknown error";

      if (error_code == ERROR_HTTP_HEADER_NOT_FOUND)
        error_str = "ERROR_HTTP_HEADER_NOT_FOUND";

      GST_WARNING_OBJECT (self, "HttpQueryInfo for header '%s' failed: %s "
          "(0x%08lx)", header_name, error_str, error_code);
    }

    return FALSE;
  }

  *header_value = *value;
  return TRUE;
}

static gboolean
gst_win_inet_src_open (GstWinInetSrc * self)
{
  const gchar *extra_headers = NULL;

  gst_win_inet_src_reset (self);

  self->inet = InternetOpen (NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
  if (self->inet == NULL)
    goto error;

  if (self->iradio_mode)
    extra_headers = "Icy-MetaData:1";   /* exactly as sent by WinAmp, no space */

  self->url = InternetOpenUrl (self->inet, self->location, extra_headers,
      (extra_headers != NULL) ? -1 : 0, INTERNET_FLAG_NO_UI, (DWORD_PTR) self);
  if (self->url == NULL)
    goto error;

  if (self->iradio_mode) {
    gint value;

    if (gst_win_inet_src_get_header_value_as_int (self, "icy-metaint", &value,
            TRUE)) {
      self->icy_caps = gst_caps_new_simple ("application/x-icy",
          "metadata-interval", G_TYPE_INT, value, NULL);
    }
  }

  return TRUE;

error:
  GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND, (NULL),
      ("Could not open location \"%s\" for reading: 0x%08lx",
          self->location, GetLastError ()));
  gst_win_inet_src_reset (self);

  return FALSE;
}

static gboolean
gst_win_inet_src_start (GstBaseSrc * basesrc)
{
  GstWinInetSrc *self = GST_WIN_INET_SRC (basesrc);

  return gst_win_inet_src_open (self);
}

static gboolean
gst_win_inet_src_stop (GstBaseSrc * basesrc)
{
  gst_win_inet_src_reset (GST_WIN_INET_SRC (basesrc));

  return TRUE;
}

static GstFlowReturn
gst_win_inet_src_create (GstPushSrc * pushsrc, GstBuffer ** buffer)
{
  GstWinInetSrc *self = GST_WIN_INET_SRC (pushsrc);
  GstBaseSrc *basesrc = GST_BASE_SRC (pushsrc);
  GstBuffer *buf = NULL;
  GstFlowReturn ret = GST_FLOW_OK;
  DWORD bytes_read = 0;

  do {
    GstCaps *caps = GST_PAD_CAPS (GST_BASE_SRC_PAD (self));

    if (self->icy_caps != NULL)
      caps = self->icy_caps;

    ret = gst_pad_alloc_buffer (GST_BASE_SRC_PAD (basesrc),
        self->cur_offset, basesrc->blocksize, caps, &buf);

    if (G_LIKELY (ret == GST_FLOW_OK)) {
      if (InternetReadFile (self->url, GST_BUFFER_DATA (buf),
              basesrc->blocksize, &bytes_read)) {
        if (bytes_read == 0) {
          if (self->poll_mode) {
            if (gst_win_inet_src_open (self)) {
              gst_buffer_unref (buf);
              buf = NULL;
            } else {
              ret = GST_FLOW_ERROR;
            }
          } else {
            GST_ERROR_OBJECT (self, "short read (eof?)");
            ret = GST_FLOW_UNEXPECTED;
          }
        }
      } else {
        GST_ERROR_OBJECT (self, "InternetReadFile failed: 0x%08lx",
            GetLastError ());

        ret = GST_FLOW_ERROR;
      }
    }
  }
  while (bytes_read == 0 && ret == GST_FLOW_OK);

  if (ret == GST_FLOW_OK) {
    GST_BUFFER_SIZE (buf) = bytes_read;
    self->cur_offset += bytes_read;

    *buffer = buf;
  } else {
    if (buf != NULL)
      gst_buffer_unref (buf);
  }

  return ret;
}

static GstURIType
gst_win_inet_src_uri_get_type (void)
{
  return GST_URI_SRC;
}

static gchar **
gst_win_inet_src_uri_get_protocols (void)
{
  static const gchar *protocols[] = { "http", "https", "ftp", NULL };

  return (gchar **) protocols;
}

static const gchar *
gst_win_inet_src_uri_get_uri (GstURIHandler * handler)
{
  GstWinInetSrc *src = GST_WIN_INET_SRC (handler);

  return src->location;
}

static gboolean
gst_win_inet_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
  GstWinInetSrc *src = GST_WIN_INET_SRC (handler);

  g_free (src->location);
  src->location = g_strdup (uri);
  return TRUE;
}

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

  iface->get_type = gst_win_inet_src_uri_get_type;
  iface->get_protocols = gst_win_inet_src_uri_get_protocols;
  iface->get_uri = gst_win_inet_src_uri_get_uri;
  iface->set_uri = gst_win_inet_src_uri_set_uri;
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "wininetsrc",
      GST_RANK_NONE, GST_TYPE_WIN_INET_SRC);
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    wininet,
    "Windows network plugins",
    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
