/* GStreamer
 * Copyright (C) 2011 Axis Communications <dev-gstreamer@axis.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-curlftpsink
 * @title: curlftpsink
 * @short_description: sink that uploads data to a server using libcurl
 * @see_also:
 *
 * This is a network sink that uses libcurl as a client to upload data to
 * an FTP server.
 *
 * ## Example launch line
 *
 * Upload a JPEG file to /home/test/images * directory)
 *
 * |[
 * gst-launch-1.0 filesrc location=image.jpg ! jpegparse ! curlftpsink  \
 *     file-name=image.jpg  \
 *     location=ftp://192.168.0.1/images/
 * ]|
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <curl/curl.h>
#include <string.h>
#include <stdio.h>

#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <sys/types.h>
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#include <unistd.h>
#if HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#if HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#include <sys/stat.h>
#include <fcntl.h>

#include "gstcurltlssink.h"
#include "gstcurlftpsink.h"

/* Default values */
#define GST_CAT_DEFAULT                gst_curl_ftp_sink_debug
#define RENAME_TO                          "RNTO "
#define RENAME_FROM			   "RNFR "

/* Plugin specific settings */

GST_DEBUG_CATEGORY_STATIC (gst_curl_ftp_sink_debug);

enum
{
  PROP_0,
  PROP_FTP_PORT_ARG,
  PROP_EPSV_MODE,
  PROP_CREATE_TEMP_FILE,
  PROP_CREATE_TEMP_FILE_NAME,
  PROP_CREATE_DIRS
};


/* Object class function declarations */


/* private functions */
static void gst_curl_ftp_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_curl_ftp_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_curl_ftp_sink_finalize (GObject * gobject);

static gboolean set_ftp_options_unlocked (GstCurlBaseSink * curlbasesink);
static gboolean set_ftp_dynamic_options_unlocked
    (GstCurlBaseSink * curlbasesink);

#define gst_curl_ftp_sink_parent_class parent_class
G_DEFINE_TYPE (GstCurlFtpSink, gst_curl_ftp_sink, GST_TYPE_CURL_TLS_SINK);

static void
gst_curl_ftp_sink_class_init (GstCurlFtpSinkClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstCurlBaseSinkClass *gstcurlbasesink_class = (GstCurlBaseSinkClass *) klass;
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (gst_curl_ftp_sink_debug, "curlftpsink", 0,
      "curl ftp sink element");
  GST_DEBUG_OBJECT (klass, "class_init");

  gst_element_class_set_static_metadata (element_class,
      "Curl ftp sink",
      "Sink/Network",
      "Upload data over FTP protocol using libcurl",
      "Patricia Muscalu <patricia@axis.com>");

  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_curl_ftp_sink_finalize);

  gobject_class->set_property = gst_curl_ftp_sink_set_property;
  gobject_class->get_property = gst_curl_ftp_sink_get_property;

  gstcurlbasesink_class->set_protocol_dynamic_options_unlocked =
      set_ftp_dynamic_options_unlocked;
  gstcurlbasesink_class->set_options_unlocked = set_ftp_options_unlocked;

  g_object_class_install_property (gobject_class, PROP_FTP_PORT_ARG,
      g_param_spec_string ("ftp-port", "IP address for FTP PORT instruction",
          "The PORT instruction tells the remote server to connect to"
          " the IP address", "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_EPSV_MODE,
      g_param_spec_boolean ("epsv-mode", "Extended passive mode",
          "Enable the use of the EPSV command when doing passive FTP transfers",
          TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_CREATE_TEMP_FILE,
      g_param_spec_boolean ("create-tmp-file", "Enable or disable temporary file transfer", "Use a temporary file name when uploading a a file. When the transfer is complete,  \
          this temporary file is renamed to the final file name. This is useful for ensuring \
          that remote systems do not read a partially uploaded file", FALSE, G_PARAM_READWRITE |
          G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_CREATE_TEMP_FILE_NAME,
      g_param_spec_string ("temp-file-name",
          "Creates a temporary file name with date and time",
          "Filename pattern to use when generating a temporary filename for uploads",
          NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_CREATE_DIRS,
      g_param_spec_boolean ("create-dirs", "Create missing directories",
          "Attempt to create missing directory included in the path", FALSE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
gst_curl_ftp_sink_init (GstCurlFtpSink * sink)
{
}

static void
gst_curl_ftp_sink_finalize (GObject * gobject)
{
  GstCurlFtpSink *this = GST_CURL_FTP_SINK (gobject);

  GST_DEBUG ("finalizing curlftpsink");
  g_free (this->ftp_port_arg);
  g_free (this->tmpfile_name);

  if (this->headerlist) {
    curl_slist_free_all (this->headerlist);
    this->headerlist = NULL;
  }

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

static gboolean
set_ftp_dynamic_options_unlocked (GstCurlBaseSink * basesink)
{
  gchar *tmp = NULL;
  GstCurlFtpSink *sink = GST_CURL_FTP_SINK (basesink);
  CURLcode res;

  if (sink->tmpfile_create) {
    gchar *rename_from = NULL;
    gchar *rename_to = NULL;
    gchar *uploadfile_as = NULL;
    gchar *last_slash = NULL;
    gchar *tmpfile_name = NULL;

    if (sink->headerlist != NULL) {
      curl_slist_free_all (sink->headerlist);
      sink->headerlist = NULL;
    }

    if (sink->tmpfile_name != NULL) {
      tmpfile_name = g_strdup_printf ("%s", sink->tmpfile_name);
    } else {
      tmpfile_name =
          g_strdup_printf (".tmp.%04X%04X", g_random_int (), g_random_int ());
    }

    rename_from = g_strdup_printf ("%s%s", RENAME_FROM, tmpfile_name);

    last_slash = strrchr (basesink->file_name, '/');
    if (last_slash != NULL) {
      gchar *dir_name =
          g_strndup (basesink->file_name, last_slash - basesink->file_name);
      rename_to = g_strdup_printf ("%s%s", RENAME_TO, last_slash + 1);
      uploadfile_as = g_strdup_printf ("%s/%s", dir_name, tmpfile_name);
      g_free (dir_name);
    } else {
      rename_to = g_strdup_printf ("%s%s", RENAME_TO, basesink->file_name);
      uploadfile_as = g_strdup_printf ("%s", tmpfile_name);
    }
    g_free (tmpfile_name);

    tmp = g_strdup_printf ("%s%s", basesink->url, uploadfile_as);
    g_free (uploadfile_as);

    sink->headerlist = curl_slist_append (sink->headerlist, rename_from);
    sink->headerlist = curl_slist_append (sink->headerlist, rename_to);
    g_free (rename_from);
    g_free (rename_to);

    res = curl_easy_setopt (basesink->curl, CURLOPT_URL, tmp);
    g_free (tmp);
    if (res != CURLE_OK) {
      basesink->error = g_strdup_printf ("failed to set URL: %s",
          curl_easy_strerror (res));
      return FALSE;
    }

    res =
        curl_easy_setopt (basesink->curl, CURLOPT_POSTQUOTE, sink->headerlist);
    if (res != CURLE_OK) {
      basesink->error = g_strdup_printf ("failed to set post quote: %s",
          curl_easy_strerror (res));
      return FALSE;
    }

    if (last_slash != NULL) {
      *last_slash = '\0';
    }
  } else {
    tmp = g_strdup_printf ("%s%s", basesink->url, basesink->file_name);
    res = curl_easy_setopt (basesink->curl, CURLOPT_URL, tmp);
    g_free (tmp);
    if (res != CURLE_OK) {
      basesink->error = g_strdup_printf ("failed to set URL: %s",
          curl_easy_strerror (res));
      return FALSE;
    }
  }

  return TRUE;
}

static gboolean
set_ftp_options_unlocked (GstCurlBaseSink * basesink)
{
  GstCurlFtpSink *sink = GST_CURL_FTP_SINK (basesink);
  CURLcode res;

  res = curl_easy_setopt (basesink->curl, CURLOPT_UPLOAD, 1L);
  if (res != CURLE_OK) {
    basesink->error = g_strdup_printf ("failed to prepare for upload: %s",
        curl_easy_strerror (res));
    return FALSE;
  }

  if (sink->ftp_port_arg != NULL && (strlen (sink->ftp_port_arg) > 0)) {
    /* Connect data stream actively. */
    res = curl_easy_setopt (basesink->curl, CURLOPT_FTPPORT,
        sink->ftp_port_arg);

    if (res != CURLE_OK) {
      basesink->error = g_strdup_printf ("failed to set up active mode: %s",
          curl_easy_strerror (res));
      return FALSE;
    }
  } else {
    /* Connect data stream passively.
     * libcurl will always attempt to use EPSV before PASV.
     */
    if (!sink->epsv_mode) {
      /* send only plain PASV command */
      res = curl_easy_setopt (basesink->curl, CURLOPT_FTP_USE_EPSV, 0);
      if (res != CURLE_OK) {
        basesink->error =
            g_strdup_printf ("failed to set extended passive mode: %s",
            curl_easy_strerror (res));
        return FALSE;
      }
    }
  }

  if (sink->create_dirs) {
    res = curl_easy_setopt (basesink->curl, CURLOPT_FTP_CREATE_MISSING_DIRS,
        1L);
    if (res != CURLE_OK) {
      basesink->error =
          g_strdup_printf ("failed to set create missing dirs: %s",
          curl_easy_strerror (res));
      return FALSE;
    }
  }

  return TRUE;
}

static void
gst_curl_ftp_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstCurlFtpSink *sink;
  GstState cur_state;

  g_return_if_fail (GST_IS_CURL_FTP_SINK (object));
  sink = GST_CURL_FTP_SINK (object);

  gst_element_get_state (GST_ELEMENT (sink), &cur_state, NULL, 0);
  if (cur_state != GST_STATE_PLAYING && cur_state != GST_STATE_PAUSED) {
    GST_OBJECT_LOCK (sink);

    switch (prop_id) {
      case PROP_FTP_PORT_ARG:
        g_free (sink->ftp_port_arg);
        sink->ftp_port_arg = g_value_dup_string (value);
        GST_DEBUG_OBJECT (sink, "ftp-port set to %s", sink->ftp_port_arg);
        break;
      case PROP_EPSV_MODE:
        sink->epsv_mode = g_value_get_boolean (value);
        GST_DEBUG_OBJECT (sink, "epsv-mode set to %d", sink->epsv_mode);
        break;
      case PROP_CREATE_TEMP_FILE:
        sink->tmpfile_create = g_value_get_boolean (value);
        GST_DEBUG_OBJECT (sink, "create-tmp-file set to %d",
            sink->tmpfile_create);
        break;
      case PROP_CREATE_TEMP_FILE_NAME:
        g_free (sink->tmpfile_name);
        sink->tmpfile_name = g_value_dup_string (value);
        GST_DEBUG_OBJECT (sink, "tmp-file-name set to %s", sink->tmpfile_name);
        break;
      case PROP_CREATE_DIRS:
        sink->create_dirs = g_value_get_boolean (value);
        GST_DEBUG_OBJECT (sink, "create-dirs set to %d", sink->create_dirs);
        break;

      default:
        GST_DEBUG_OBJECT (sink, "invalid property id %d", prop_id);
        break;
    }

    GST_OBJECT_UNLOCK (sink);
  }
}

static void
gst_curl_ftp_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstCurlFtpSink *sink;

  g_return_if_fail (GST_IS_CURL_FTP_SINK (object));
  sink = GST_CURL_FTP_SINK (object);

  switch (prop_id) {
    case PROP_FTP_PORT_ARG:
      g_value_set_string (value, sink->ftp_port_arg);
      break;
    case PROP_EPSV_MODE:
      g_value_set_boolean (value, sink->epsv_mode);
      break;
    case PROP_CREATE_TEMP_FILE:
      g_value_set_boolean (value, sink->tmpfile_create);
      break;
    case PROP_CREATE_TEMP_FILE_NAME:
      g_value_set_string (value, sink->tmpfile_name);
      break;
    case PROP_CREATE_DIRS:
      g_value_set_boolean (value, sink->create_dirs);
      break;
    default:
      GST_DEBUG_OBJECT (sink, "invalid property id");
      break;
  }
}
