/*
 *
 *  OBEX Client
 *
 *  Copyright (C) 2007-2010  Marcel Holtmann <marcel@holtmann.org>
 *  Copyright (C) 2011-2012  BMW Car IT GmbH. All rights reserved.
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

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

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <inttypes.h>

#include <glib.h>
#include <gdbus/gdbus.h>
#include <gobex/gobex.h>

#include "dbus.h"
#include "log.h"
#include "transfer.h"

#define TRANSFER_INTERFACE "org.bluez.obex.Transfer1"
#define ERROR_INTERFACE "org.bluez.obex.Error"

#define OBC_TRANSFER_ERROR obc_transfer_error_quark()

#define FIRST_PACKET_TIMEOUT 60

static guint64 counter = 0;

struct transfer_callback {
	transfer_callback_t func;
	void *data;
};

enum {
	TRANSFER_STATUS_QUEUED = 0,
	TRANSFER_STATUS_ACTIVE,
	TRANSFER_STATUS_COMPLETE,
	TRANSFER_STATUS_ERROR
};

struct obc_transfer {
	GObex *obex;
	uint8_t status;
	GObexApparam *apparam;
	guint8 op;
	struct transfer_callback *callback;
	DBusConnection *conn;
	DBusMessage *msg;
	char *session;		/* Session path */
	char *owner;		/* Transfer initiator */
	char *path;		/* Transfer path */
	char *filename;		/* Transfer file location */
	char *name;		/* Transfer object name */
	char *type;		/* Transfer object type */
	int fd;
	guint xfer;
	gint64 size;
	gint64 transferred;
	gint64 progress;
	guint progress_id;
};

static GQuark obc_transfer_error_quark(void)
{
	return g_quark_from_static_string("obc-transfer-error-quark");
}

DBusMessage *obc_transfer_create_dbus_reply(struct obc_transfer *transfer,
							DBusMessage *message)
{
	DBusMessage *reply;
	DBusMessageIter iter;

	reply = dbus_message_new_method_return(message);
	if (reply == NULL)
		return NULL;

	dbus_message_iter_init_append(reply, &iter);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
							&transfer->path);
	g_dbus_get_properties(transfer->conn, transfer->path,
						TRANSFER_INTERFACE, &iter);

	return reply;
}

static void abort_complete(GObex *obex, GError *err, gpointer user_data)
{
	struct obc_transfer *transfer = user_data;
	struct transfer_callback *callback = transfer->callback;
	DBusMessage *reply;

	transfer->xfer = 0;

	reply = dbus_message_new_method_return(transfer->msg);
	if (reply)
		g_dbus_send_message(transfer->conn, reply);

	dbus_message_unref(transfer->msg);
	transfer->msg = NULL;

	if (callback == NULL)
		return;

	if (err) {
		callback->func(transfer, err, callback->data);
	} else {
		GError *abort_err;

		abort_err = g_error_new(OBC_TRANSFER_ERROR, -ECANCELED, "%s",
						"Transfer cancelled by user");
		callback->func(transfer, abort_err, callback->data);
		g_error_free(abort_err);
	}
}

static DBusMessage *obc_transfer_cancel(DBusConnection *connection,
					DBusMessage *message, void *user_data)
{
	struct obc_transfer *transfer = user_data;
	const char *sender;

	sender = dbus_message_get_sender(message);
	if (g_strcmp0(transfer->owner, sender) != 0)
		return g_dbus_create_error(message,
				ERROR_INTERFACE ".NotAuthorized",
				"Not Authorized");

	if (transfer->msg != NULL)
		return g_dbus_create_error(message,
				ERROR_INTERFACE ".InProgress",
				"Cancellation already in progress");

	if (transfer->xfer == 0) {
		struct transfer_callback *callback = transfer->callback;

		if (callback != NULL) {
			GError *err;

			err = g_error_new(OBC_TRANSFER_ERROR, -ECANCELED, "%s",
						"Transfer cancelled by user");
			callback->func(transfer, err, callback->data);
			g_error_free(err);
		}

		return dbus_message_new_method_return(message);
	}

	if (transfer->progress_id != 0) {
		g_source_remove(transfer->progress_id);
		transfer->progress_id = 0;
	}

	if (!g_obex_cancel_transfer(transfer->xfer, abort_complete, transfer))
		return g_dbus_create_error(message,
				ERROR_INTERFACE ".Failed",
				"Failed");

	transfer->msg = dbus_message_ref(message);

	return NULL;
}

static gboolean name_exists(const GDBusPropertyTable *property, void *data)
{
	struct obc_transfer *transfer = data;

	return transfer->name != NULL;
}

static gboolean get_name(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct obc_transfer *transfer = data;

	if (transfer->name == NULL)
		return FALSE;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
							&transfer->name);

	return TRUE;
}

static gboolean get_size(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct obc_transfer *transfer = data;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64,
							&transfer->size);

	return TRUE;
}

static gboolean filename_exists(const GDBusPropertyTable *property, void *data)
{
	struct obc_transfer *transfer = data;

	return transfer->filename != NULL;
}

static gboolean get_filename(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct obc_transfer *transfer = data;

	if (transfer->filename == NULL)
		return FALSE;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
							&transfer->filename);

	return TRUE;
}

static gboolean transferred_exists(const GDBusPropertyTable *property,
								void *data)
{
	struct obc_transfer *transfer = data;

	return transfer->obex != NULL;
}

static gboolean get_transferred(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct obc_transfer *transfer = data;

	if (transfer->obex == NULL)
		return FALSE;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64,
							&transfer->progress);

	return TRUE;
}

static const char *status2str(uint8_t status)
{
	switch (status) {
	case TRANSFER_STATUS_QUEUED:
		return "queued";
	case TRANSFER_STATUS_ACTIVE:
		return "active";
	case TRANSFER_STATUS_COMPLETE:
		return "complete";
	case TRANSFER_STATUS_ERROR:
	default:
		return "error";
	}
}

static gboolean get_status(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct obc_transfer *transfer = data;
	const char *status = status2str(transfer->status);

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &status);

	return TRUE;
}

static gboolean get_session(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct obc_transfer *transfer = data;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
							&transfer->session);

	return TRUE;
}

static const GDBusMethodTable obc_transfer_methods[] = {
	{ GDBUS_ASYNC_METHOD("Cancel", NULL, NULL,
				obc_transfer_cancel) },
	{ }
};

static const GDBusPropertyTable obc_transfer_properties[] = {
	{ "Status", "s", get_status },
	{ "Name", "s", get_name, NULL, name_exists },
	{ "Size", "t", get_size },
	{ "Filename", "s", get_filename, NULL, filename_exists },
	{ "Transferred", "t", get_transferred, NULL, transferred_exists },
	{ "Session", "o", get_session },
	{ }
};

static void obc_transfer_free(struct obc_transfer *transfer)
{
	DBG("%p", transfer);

	if (transfer->xfer)
		g_obex_cancel_transfer(transfer->xfer, NULL, NULL);

	if (transfer->progress_id != 0) {
		g_source_remove(transfer->progress_id);
		transfer->progress_id = 0;
	}

	if (transfer->op == G_OBEX_OP_GET &&
				transfer->status != TRANSFER_STATUS_COMPLETE &&
				transfer->filename)
		remove(transfer->filename);

	if (transfer->fd > 0)
		close(transfer->fd);

	if (transfer->apparam != NULL)
		g_obex_apparam_free(transfer->apparam);

	if (transfer->conn)
		dbus_connection_unref(transfer->conn);

	if (transfer->msg)
		dbus_message_unref(transfer->msg);

	if (transfer->obex)
		g_obex_unref(transfer->obex);

	g_free(transfer->callback);
	g_free(transfer->owner);
	g_free(transfer->filename);
	g_free(transfer->name);
	g_free(transfer->type);
	g_free(transfer->session);
	g_free(transfer->path);
	g_free(transfer);
}

static struct obc_transfer *obc_transfer_create(guint8 op,
						const char *filename,
						const char *name,
						const char *type)
{
	struct obc_transfer *transfer;

	transfer = g_new0(struct obc_transfer, 1);
	transfer->op = op;
	transfer->filename = g_strdup(filename);
	transfer->name = g_strdup(name);
	transfer->type = g_strdup(type);

	return transfer;
}

gboolean obc_transfer_register(struct obc_transfer *transfer,
						DBusConnection *conn,
						const char *session,
						const char *owner,
						GError **err)
{
	transfer->owner = g_strdup(owner);

	transfer->session = g_strdup(session);
	transfer->path = g_strdup_printf("%s/transfer%ju", session, counter++);

	transfer->conn = dbus_connection_ref(conn);
	if (transfer->conn == NULL) {
		g_set_error(err, OBC_TRANSFER_ERROR, -EFAULT,
						"Unable to connect to D-Bus");
		return FALSE;
	}

	if (g_dbus_register_interface(transfer->conn, transfer->path,
				TRANSFER_INTERFACE,
				obc_transfer_methods, NULL,
				obc_transfer_properties, transfer,
				NULL) == FALSE) {
		g_set_error(err, OBC_TRANSFER_ERROR, -EFAULT,
						"Unable to register to D-Bus");
		return FALSE;
	}

	DBG("%p registered %s", transfer, transfer->path);

	return TRUE;
}

static gboolean transfer_open(struct obc_transfer *transfer, int flags,
						mode_t mode, GError **err)
{
	int fd;
	char *filename;

	if (transfer->filename != NULL && strcmp(transfer->filename, "") != 0) {
		fd = open(transfer->filename, flags, mode);
		if (fd < 0) {
			error("open(): %s(%d)", strerror(errno), errno);
			g_set_error(err, OBC_TRANSFER_ERROR, -errno,
							"Unable to open file");
			return FALSE;
		}
		goto done;
	}

	fd = g_file_open_tmp("obex-clientXXXXXX", &filename, err);
	if (fd < 0) {
		error("g_file_open_tmp(): %s", (*err)->message);
		return FALSE;
	}

	if (transfer->filename == NULL) {
		remove(filename); /* remove always only if NULL was given */
		g_free(filename);
	} else {
		g_free(transfer->filename);
		transfer->filename = filename;
	}

done:
	transfer->fd = fd;
	return TRUE;
}

struct obc_transfer *obc_transfer_get(const char *type, const char *name,
					const char *filename, GError **err)
{
	struct obc_transfer *transfer;
	int perr;

	transfer = obc_transfer_create(G_OBEX_OP_GET, filename, name, type);

	perr = transfer_open(transfer, O_WRONLY | O_CREAT | O_TRUNC, 0600, err);
	if (perr < 0) {
		obc_transfer_free(transfer);
		return NULL;
	}

	return transfer;
}

struct obc_transfer *obc_transfer_put(const char *type, const char *name,
					const char *filename,
					const void *contents, size_t size,
					GError **err)
{
	struct obc_transfer *transfer;
	struct stat st;
	int perr;

	if ((filename == NULL || strcmp(filename, "") == 0) &&
							contents == NULL) {
		g_set_error(err, OBC_TRANSFER_ERROR, -EINVAL,
						"Invalid filename given");
		return NULL;
	}

	transfer = obc_transfer_create(G_OBEX_OP_PUT, filename, name, type);

	if (contents != NULL) {
		ssize_t w;

		if (!transfer_open(transfer, O_RDWR, 0, err))
			goto fail;

		w = write(transfer->fd, contents, size);
		if (w < 0) {
			perr = errno;
			error("write(): %s(%d)", strerror(perr), perr);
			g_set_error(err, OBC_TRANSFER_ERROR, -perr,
						"Writing to file failed");
			goto fail;
		} else if ((size_t) w != size) {
			error("Unable to write all contents to file");
			g_set_error(err, OBC_TRANSFER_ERROR, -EFAULT,
					"Writing all contents to file failed");
			goto fail;
		}
		lseek(transfer->fd, 0, SEEK_SET);
	} else {
		if (!transfer_open(transfer, O_RDONLY, 0, err))
			goto fail;
	}

	if (fstat(transfer->fd, &st) < 0) {
		perr = errno;
		error("fstat(): %s(%d)", strerror(perr), perr);
		g_set_error(err, OBC_TRANSFER_ERROR, -perr,
						"Unable to get file status");
		goto fail;
	}

	transfer->size = st.st_size;

	return transfer;

fail:
	obc_transfer_free(transfer);
	return NULL;
}

void obc_transfer_unregister(struct obc_transfer *transfer)
{
	if (transfer->path) {
		g_dbus_unregister_interface(transfer->conn,
			transfer->path, TRANSFER_INTERFACE);
	}

	DBG("%p unregistered %s", transfer, transfer->path);

	obc_transfer_free(transfer);
}

static gboolean get_xfer_progress(const void *buf, gsize len,
							gpointer user_data)
{
	struct obc_transfer *transfer = user_data;

	if (transfer->fd > 0) {
		int w;

		w = write(transfer->fd, buf, len);
		if (w < 0)
			return FALSE;

		transfer->transferred += w;
	}

	return TRUE;
}

static void transfer_set_status(struct obc_transfer *transfer, uint8_t status)
{
	transfer->status = status;

	g_dbus_emit_property_changed(transfer->conn, transfer->path,
					TRANSFER_INTERFACE, "Status");
}

static void xfer_complete(GObex *obex, GError *err, gpointer user_data)
{
	struct obc_transfer *transfer = user_data;
	struct transfer_callback *callback = transfer->callback;

	transfer->xfer = 0;

	if (transfer->progress_id != 0) {
		g_source_remove(transfer->progress_id);
		transfer->progress_id = 0;
	}

	if (err)
		transfer_set_status(transfer, TRANSFER_STATUS_ERROR);
	else
		transfer_set_status(transfer, TRANSFER_STATUS_COMPLETE);

	if (callback)
		callback->func(transfer, err, callback->data);
}

static void get_xfer_progress_first(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct obc_transfer *transfer = user_data;
	GObexPacket *req;
	GObexHeader *hdr;
	GObexApparam *apparam;
	const guint8 *buf;
	gsize len;
	guint8 rspcode;
	gboolean final;

	if (err != NULL) {
		xfer_complete(obex, err, transfer);
		return;
	}

	rspcode = g_obex_packet_get_operation(rsp, &final);
	if (rspcode != G_OBEX_RSP_SUCCESS && rspcode != G_OBEX_RSP_CONTINUE) {
		err = g_error_new(OBC_TRANSFER_ERROR, rspcode, "%s",
						g_obex_strerror(rspcode));
		xfer_complete(obex, err, transfer);
		g_error_free(err);
		return;
	}

	hdr = g_obex_packet_get_header(rsp, G_OBEX_HDR_LENGTH);
	if (hdr) {
		uint32_t len;
		if (g_obex_header_get_uint32(hdr, &len)) {
			transfer->size = len;
			g_dbus_emit_property_changed(transfer->conn,
						transfer->path,
						TRANSFER_INTERFACE, "Size");
		}
	}

	hdr = g_obex_packet_get_header(rsp, G_OBEX_HDR_APPARAM);
	if (hdr) {
		apparam = g_obex_header_get_apparam(hdr);
		if (apparam != NULL)
			obc_transfer_set_apparam(transfer, apparam);
	}

	hdr = g_obex_packet_get_body(rsp);
	if (hdr) {
		g_obex_header_get_bytes(hdr, &buf, &len);
		if (len != 0)
			get_xfer_progress(buf, len, transfer);
	}

	if (rspcode == G_OBEX_RSP_SUCCESS) {
		xfer_complete(obex, err, transfer);
		return;
	}

	if (!g_obex_srm_active(obex)) {
		req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_INVALID);

		transfer->xfer = g_obex_get_req_pkt(obex, req, get_xfer_progress,
						xfer_complete, transfer,
						&err);
	}
}

static gssize put_xfer_progress(void *buf, gsize len, gpointer user_data)
{
	struct obc_transfer *transfer = user_data;
	gssize size;

	size = read(transfer->fd, buf, len);
	if (size <= 0)
		return size;

	transfer->transferred += size;

	return size;
}

gboolean obc_transfer_set_callback(struct obc_transfer *transfer,
					transfer_callback_t func,
					void *user_data)
{
	struct transfer_callback *callback;

	if (transfer->callback != NULL)
		return FALSE;

	callback = g_new0(struct transfer_callback, 1);
	callback->func = func;
	callback->data = user_data;

	transfer->callback = callback;

	return TRUE;
}

static gboolean report_progress(gpointer data)
{
	struct obc_transfer *transfer = data;

	if (transfer->transferred == transfer->progress)
		return TRUE;

	transfer->progress = transfer->transferred;

	if (transfer->transferred == transfer->size) {
		transfer->progress_id = 0;
		return FALSE;
	}

	if (transfer->status != TRANSFER_STATUS_ACTIVE)
		transfer_set_status(transfer, TRANSFER_STATUS_ACTIVE);

	g_dbus_emit_property_changed(transfer->conn, transfer->path,
					TRANSFER_INTERFACE, "Transferred");

	return TRUE;
}

static gboolean transfer_start_get(struct obc_transfer *transfer, GError **err)
{
	GObexPacket *req;
	GObexHeader *hdr;

	if (transfer->xfer > 0) {
		g_set_error(err, OBC_TRANSFER_ERROR, -EALREADY,
						"Transfer already started");
		return FALSE;
	}

	req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_INVALID);

	if (transfer->name != NULL)
		g_obex_packet_add_unicode(req, G_OBEX_HDR_NAME,
							transfer->name);

	if (transfer->type != NULL)
		g_obex_packet_add_bytes(req, G_OBEX_HDR_TYPE, transfer->type,
						strlen(transfer->type) + 1);

	if (transfer->apparam != NULL) {
		hdr = g_obex_header_new_apparam(transfer->apparam);
		g_obex_packet_add_header(req, hdr);
	}

	transfer->xfer = g_obex_send_req(transfer->obex, req,
						FIRST_PACKET_TIMEOUT,
						get_xfer_progress_first,
						transfer, err);
	if (transfer->xfer == 0)
		return FALSE;

	if (transfer->path == NULL)
		return TRUE;

	transfer->progress_id = g_timeout_add_seconds(1, report_progress,
								transfer);

	return TRUE;
}

static gboolean transfer_start_put(struct obc_transfer *transfer, GError **err)
{
	GObexPacket *req;
	GObexHeader *hdr;

	if (transfer->xfer > 0) {
		g_set_error(err, OBC_TRANSFER_ERROR, -EALREADY,
						"Transfer already started");
		return FALSE;
	}

	req = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, G_OBEX_HDR_INVALID);

	if (transfer->name != NULL)
		g_obex_packet_add_unicode(req, G_OBEX_HDR_NAME,
							transfer->name);

	if (transfer->type != NULL)
		g_obex_packet_add_bytes(req, G_OBEX_HDR_TYPE, transfer->type,
						strlen(transfer->type) + 1);

	if (transfer->size < UINT32_MAX)
		g_obex_packet_add_uint32(req, G_OBEX_HDR_LENGTH, transfer->size);

	if (transfer->apparam != NULL) {
		hdr = g_obex_header_new_apparam(transfer->apparam);
		g_obex_packet_add_header(req, hdr);
	}

	transfer->xfer = g_obex_put_req_pkt(transfer->obex, req,
					put_xfer_progress, xfer_complete,
					transfer, err);
	if (transfer->xfer == 0)
		return FALSE;

	if (transfer->path == NULL)
		return TRUE;

	transfer->progress_id = g_timeout_add_seconds(1, report_progress,
								transfer);

	return TRUE;
}

gboolean obc_transfer_start(struct obc_transfer *transfer, void *obex,
								GError **err)
{
	transfer->obex = g_obex_ref(obex);

	switch (transfer->op) {
	case G_OBEX_OP_GET:
		return transfer_start_get(transfer, err);
	case G_OBEX_OP_PUT:
		return transfer_start_put(transfer, err);
	}

	g_set_error(err, OBC_TRANSFER_ERROR, -ENOTSUP, "Not supported");
	return FALSE;
}

guint8 obc_transfer_get_operation(struct obc_transfer *transfer)
{
	return transfer->op;
}

void obc_transfer_set_apparam(struct obc_transfer *transfer, void *data)
{
	if (transfer->apparam != NULL)
		g_obex_apparam_free(transfer->apparam);

	if (data == NULL)
		return;

	transfer->apparam = data;
}

void *obc_transfer_get_apparam(struct obc_transfer *transfer)
{
	return transfer->apparam;
}

int obc_transfer_get_contents(struct obc_transfer *transfer, char **contents,
								size_t *size)
{
	struct stat st;
	ssize_t ret;

	if (contents == NULL)
		return -EINVAL;

	if (fstat(transfer->fd, &st) < 0) {
		error("fstat(): %s(%d)", strerror(errno), errno);
		return -errno;
	}

	if (lseek(transfer->fd, 0, SEEK_SET) < 0) {
		error("lseek(): %s(%d)", strerror(errno), errno);
		return -errno;
	}

	*contents = g_malloc(st.st_size + 1);

	ret = read(transfer->fd, *contents, st.st_size);
	if (ret < 0) {
		error("read(): %s(%d)", strerror(errno), errno);
		g_free(*contents);
		return -errno;
	}

	(*contents)[ret] = '\0';

	if (size)
		*size = ret;

	return 0;
}

const char *obc_transfer_get_path(struct obc_transfer *transfer)
{
	return transfer->path;
}

gint64 obc_transfer_get_size(struct obc_transfer *transfer)
{
	return transfer->size;
}
