/* 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
 * @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.
 *
 * <refsect2>
 * <title>Example launch line (upload a JPEG file to /home/test/images
 * directory)</title>
 * |[
 * gst-launch-1.0 filesrc location=image.jpg ! jpegparse ! curlftpsink  \
 *     file-name=image.jpg  \
 *     location=ftp://192.168.0.1/images/
 * ]|
 * </refsect2>
 */

#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;
  }
}
