/*
 * GstCurlHttpSrc
 * Copyright 2017 British Broadcasting Corporation - Research and Development
 *
 * Author: Sam Hurst <samuelh@rd.bbc.co.uk>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Alternatively, the contents of this file may be used under the
 * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
 * which case the following provisions apply instead of the ones
 * mentioned above:
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * This header file contains definitions only for
 */

#ifndef GSTCURLHTTPSRC_H_
#define GSTCURLHTTPSRC_H_

#include <gst/gst.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <gst/base/gstpushsrc.h>

#include "curltask.h"

G_BEGIN_DECLS
/* #defines don't like whitespacey bits */
#define GST_TYPE_CURLHTTPSRC \
  (gst_curl_http_src_get_type())
#define GST_CURLHTTPSRC(obj) \
  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CURLHTTPSRC,GstCurlHttpSrc))
#define GST_CURLHTTPSRC_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CURLHTTPSRC,GstCurlHttpSrcClass))
#define GST_IS_CURLHTTPSRC(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CURLHTTPSRC))
#define GST_IS_CURLHTTPSRC_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CURLHTTPSRC))

#if GSTCURL_FUNCTIONTRACE
#define GSTCURL_FUNCTION_ENTRY(x) GST_DEBUG_OBJECT(x, "Entering function");
#define GSTCURL_FUNCTION_EXIT(x) GST_DEBUG_OBJECT(x, "Leaving function");
#else
#define GSTCURL_FUNCTION_ENTRY(x)
#define GSTCURL_FUNCTION_EXIT(x)
#endif
typedef struct _GstCurlHttpSrc GstCurlHttpSrc;
typedef struct _GstCurlHttpSrcClass GstCurlHttpSrcClass;
typedef struct _GstCurlHttpSrcMultiTaskContext GstCurlHttpSrcMultiTaskContext;
typedef struct _GstCurlHttpSrcQueueElement GstCurlHttpSrcQueueElement;

#define HTTP_HEADERS_NAME       "http-headers"
#define HTTP_STATUS_CODE        "http-status-code"
#define URI_NAME                "uri"
#define REQUEST_HEADERS_NAME    "request-headers"
#define RESPONSE_HEADERS_NAME   "response-headers"
#define REDIRECT_URI_NAME       "redirection-uri"

typedef enum
  {
    GSTCURL_HTTP_VERSION_1_0,
    GSTCURL_HTTP_VERSION_1_1,
#ifdef CURL_VERSION_HTTP2
    GSTCURL_HTTP_VERSION_2_0,
#endif
    GSTCURL_HTTP_NOT,           /* For future use, incase not HTTP protocol! */
    GSTCURL_HTTP_VERSION_MAX
  } GstCurlHttpVersion;

struct _GstCurlHttpSrcMultiTaskContext
{
  GstTask     *task;
  GRecMutex   task_rec_mutex;
  GMutex      mutex;
  guint       refcount;
  GCond       signal;

  GstCurlHttpSrc  *request_removal_element;

  GstCurlHttpSrcQueueElement  *queue;

  enum
  {
    GSTCURL_MULTI_LOOP_STATE_WAIT = 0,
    GSTCURL_MULTI_LOOP_STATE_QUEUE_EVENT,
    GSTCURL_MULTI_LOOP_STATE_RUNNING,
    GSTCURL_MULTI_LOOP_STATE_REQUEST_REMOVAL,
    GSTCURL_MULTI_LOOP_STATE_STOP,
    GSTCURL_MULTI_LOOP_STATE_MAX
  } state;

  /* < private > */
  CURLM *multi_handle;
};

struct _GstCurlHttpSrcClass
{
  GstPushSrcClass parent_class;

  GstCurlHttpSrcMultiTaskContext multi_task_context;
};

/*
 * Our instance class.
 */
struct _GstCurlHttpSrc
{
  GstPushSrc element;

  /* < private > */
  GMutex uri_mutex; /* Make the URIHandler get/set thread safe */
  /*
   * Things to tell libcURL about to build up the request message.
   */
  /* Type         Name                                      Curl Option */
  gchar *uri;                   /* CURLOPT_URL */
  gchar *redirect_uri;		/* CURLINFO_REDIRECT_URL */
  gchar *username;              /* CURLOPT_USERNAME */
  gchar *password;              /* CURLOPT_PASSWORD */
  gchar *proxy_uri;             /* CURLOPT_PROXY */
  gchar *no_proxy_list;         /* CURLOPT_NOPROXY */
  gchar *proxy_user;            /* CURLOPT_PROXYUSERNAME */
  gchar *proxy_pass;            /* CURLOPT_PROXYPASSWORD */

  /* Header options */
  gchar **cookies;              /* CURLOPT_COOKIELIST */
  gint number_cookies;
  gchar *user_agent;            /* CURLOPT_USERAGENT */
  GstStructure *request_headers;  /* CURLOPT_HTTPHEADER */
  struct curl_slist *slist;
  gboolean accept_compressed_encodings; /* CURLOPT_ACCEPT_ENCODING */

  /* Connection options */
  glong allow_3xx_redirect;     /* CURLOPT_FOLLOWLOCATION */
  glong max_3xx_redirects;      /* CURLOPT_MAXREDIRS */
  gboolean keep_alive;          /* CURLOPT_TCP_KEEPALIVE */
  gint timeout_secs;            /* CURLOPT_TIMEOUT */
  gboolean strict_ssl;		/* CURLOPT_SSL_VERIFYPEER */
  gchar* custom_ca_file;	/* CURLOPT_CAINFO */

  gint total_retries;
  gint retries_remaining;

  /*TODO As the following are all multi options, move these to curl task */
  guint max_connection_time;    /* */
  guint max_conns_per_server;   /* CURLMOPT_MAX_HOST_CONNECTIONS */
  guint max_conns_per_proxy;    /* ?!? */
  guint max_conns_global;       /* CURLMOPT_MAXCONNECTS */
  /* END multi options */

  /* Some stuff for HTTP/2 */
  GstCurlHttpVersion preferred_http_version;

  enum
  {
    GSTCURL_NONE,
    GSTCURL_OK,
    GSTCURL_DONE,
    GSTCURL_UNLOCK,
    GSTCURL_REMOVED,
    GSTCURL_BAD_QUEUE_REQUEST,
    GSTCURL_TOTAL_ERROR,
    GSTCURL_PIPELINE_NULL,
    GSTCURL_MAX
  } state, pending_state;
  CURL *curl_handle;
  GMutex buffer_mutex;
  GCond signal;
  gchar *buffer;
  guint buffer_len;
  gboolean transfer_begun;
  gboolean data_received;

  /*
   * Response Headers
   */
  GstStructure *http_headers;
  gchar *content_type;
  guint status_code;
  gboolean hdrs_updated;

  CURLcode curl_result;
  char curl_errbuf[CURL_ERROR_SIZE];

  GstCaps *caps;
};

enum
{
  PROP_0,
  PROP_URI,
  PROP_USERNAME,
  PROP_PASSWORD,
  PROP_PROXYURI,
  PROP_PROXYUSERNAME,
  PROP_PROXYPASSWORD,
  PROP_COOKIES,
  PROP_USERAGENT,
  PROP_HEADERS,
  PROP_COMPRESS,
  PROP_REDIRECT,
  PROP_MAXREDIRECT,
  PROP_KEEPALIVE,
  PROP_TIMEOUT,
  PROP_STRICT_SSL,
  PROP_SSL_CA_FILE,
  PROP_RETRIES,
  PROP_CONNECTIONMAXTIME,
  PROP_MAXCONCURRENT_SERVER,
  PROP_MAXCONCURRENT_PROXY,
  PROP_MAXCONCURRENT_GLOBAL,
  PROP_HTTPVERSION,
  PROP_MAX
};

GType gst_curl_http_src_get_type (void);

G_END_DECLS
#endif /* GSTCURLHTTPSRC_H_ */
