/*
 *
 *  OBEX IrMC Sync Server
 *
 *  Copyright (C) 2010  Marcel Mol <marcel@mesa.nl>
 *
 *  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 <stdio.h>
#include <string.h>
#include <errno.h>
#include <glib.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <inttypes.h>

#include "obexd.h"
#include "plugin.h"
#include "log.h"
#include "obex.h"
#include "service.h"
#include "phonebook.h"
#include "mimetype.h"
#include "filesystem.h"
#include "manager.h"

struct aparam_header {
	uint8_t tag;
	uint8_t len;
	uint8_t val[0];
} __attribute__ ((packed));

#define DID_LEN 18

struct irmc_session {
	struct obex_session *os;
	struct apparam_field *params;
	uint16_t entries;
	GString *buffer;
	char sn[DID_LEN];
	char did[DID_LEN];
	char manu[DID_LEN];
	char model[DID_LEN];
	void *request;
};

#define IRMC_TARGET_SIZE 9

static const guint8 IRMC_TARGET[IRMC_TARGET_SIZE] = {
			0x49, 0x52, 0x4d, 0x43,  0x2d, 0x53, 0x59, 0x4e, 0x43 };

/* FIXME:
 * the IrMC specs state the first vcard should be the owner
 * vcard. As there is no simple way to collect ownerdetails
 * just create an empty vcard (which is allowed according to the
 * specs).
 */
static const char *owner_vcard =
		"BEGIN:VCARD\r\n"
		"VERSION:2.1\r\n"
		"N:\r\n"
		"TEL:\r\n"
		"X-IRMX-LUID:0\r\n"
		"END:VCARD\r\n";

static void phonebook_size_result(const char *buffer, size_t bufsize,
					int vcards, int missed,
					gboolean lastpart, void *user_data)
{
	struct irmc_session *irmc = user_data;

	DBG("vcards %d", vcards);

	irmc->params->maxlistcount = vcards;

	if (irmc->request) {
		phonebook_req_finalize(irmc->request);
		irmc->request = NULL;
	}
}

static void query_result(const char *buffer, size_t bufsize, int vcards,
				int missed, gboolean lastpart, void *user_data)
{
	struct irmc_session *irmc = user_data;
	const char *s, *t;

	DBG("bufsize %zu vcards %d missed %d", bufsize, vcards, missed);

	if (irmc->request) {
		phonebook_req_finalize(irmc->request);
		irmc->request = NULL;
	}

	/* first add a 'owner' vcard */
	if (!irmc->buffer)
		irmc->buffer = g_string_new(owner_vcard);
	else
		irmc->buffer = g_string_append(irmc->buffer, owner_vcard);

	if (buffer == NULL)
		goto done;

	/* loop around buffer and add X-IRMC-LUID attribs */
	s = buffer;
	while ((t = strstr(s, "UID:")) != NULL) {
		/* add up to UID: into buffer */
		irmc->buffer = g_string_append_len(irmc->buffer, s, t-s);
		/*
		 * add UID: line into buffer
		 * Not sure if UID is still needed if X-IRMC-LUID is there
		 */
		s = t;
		t = strstr(s, "\r\n");
		t += 2;
		irmc->buffer = g_string_append_len(irmc->buffer, s, t-s);
		/* add X-IRMC-LUID with same number as UID */
		irmc->buffer = g_string_append_len(irmc->buffer,
							"X-IRMC-LUID:", 12);
		s += 4; /* point to uid number */
		irmc->buffer = g_string_append_len(irmc->buffer, s, t-s);
		s = t;
	}
	/* add remaining bit of buffer */
	irmc->buffer = g_string_append(irmc->buffer, s);

done:
	obex_object_set_io_flags(irmc, G_IO_IN, 0);
}

static void *irmc_connect(struct obex_session *os, int *err)
{
	struct irmc_session *irmc;
	struct apparam_field *param;
	int ret;

	DBG("");

	manager_register_session(os);

	irmc = g_new0(struct irmc_session, 1);
	irmc->os = os;

	/* FIXME:
	 * Ideally get capabilities info here and use that to define
	 * IrMC DID and SN etc parameters.
	 * For now lets used hostname and some 'random' value
	 */
	gethostname(irmc->did, DID_LEN);
	strncpy(irmc->sn, "12345", sizeof(irmc->sn) - 1);
	strncpy(irmc->manu, "obex", sizeof(irmc->manu) - 1);
	strncpy(irmc->model, "mymodel", sizeof(irmc->model) - 1);

	/* We need to know the number of contact/cal/nt entries
	 * somewhere so why not do it now.
	 */
	param = g_new0(struct apparam_field, 1);
	param->maxlistcount = 0; /* to count the number of vcards... */
	param->filter = 0x200085; /* UID TEL N VERSION */
	irmc->params = param;
	irmc->request = phonebook_pull(PB_CONTACTS, irmc->params,
					phonebook_size_result, irmc, err);
	ret = phonebook_pull_read(irmc->request);
	if (err)
		*err = ret;

	return irmc;
}

static int irmc_get(struct obex_session *os, void *user_data)
{
	struct irmc_session *irmc = user_data;
	const char *type = obex_get_type(os);
	const char *name = obex_get_name(os);
	char *path;
	int ret;

	DBG("name %s type %s irmc %p", name, type ? type : "NA", irmc);

	path = g_strdup(name);

	ret = obex_get_stream_start(os, path);

	g_free(path);

	return ret;
}

static void irmc_disconnect(struct obex_session *os, void *user_data)
{
	struct irmc_session *irmc = user_data;

	DBG("");

	manager_unregister_session(os);

	if (irmc->params) {
		if (irmc->params->searchval)
			g_free(irmc->params->searchval);
		g_free(irmc->params);
	}

	if (irmc->buffer)
		g_string_free(irmc->buffer, TRUE);

	g_free(irmc);
}

static int irmc_chkput(struct obex_session *os, void *user_data)
{
	DBG("");
	/* Reject all PUTs */
	return -EBADR;
}

static int irmc_open_devinfo(struct irmc_session *irmc)
{
	if (!irmc->buffer)
		irmc->buffer = g_string_new("");

	g_string_append_printf(irmc->buffer,
				"MANU:%s\r\n"
				"MOD:%s\r\n"
				"SN:%s\r\n"
				"IRMC-VERSION:1.1\r\n"
				"PB-TYPE-TX:VCARD2.1\r\n"
				"PB-TYPE-RX:NONE\r\n"
				"CAL-TYPE-TX:NONE\r\n"
				"CAL-TYPE-RX:NONE\r\n"
				"MSG-TYPE-TX:NONE\r\n"
				"MSG-TYPE-RX:NONE\r\n"
				"NOTE-TYPE-TX:NONE\r\n"
				"NOTE-TYPE-RX:NONE\r\n",
				irmc->manu, irmc->model, irmc->sn);

	return 0;
}

static int irmc_open_pb(struct irmc_session *irmc)
{
	int ret;

	/* how can we tell if the vcard count call already finished? */
	irmc->request = phonebook_pull(PB_CONTACTS, irmc->params,
						query_result, irmc, &ret);
	if (ret < 0) {
		DBG("phonebook_pull failed...");
		return ret;
	}

	ret = phonebook_pull_read(irmc->request);
	if (ret < 0) {
		DBG("phonebook_pull_read failed...");
		return ret;
	}

	return 0;
}

static int irmc_open_info(struct irmc_session *irmc)
{
	if (irmc->buffer == NULL)
		irmc->buffer = g_string_new("");

	g_string_printf(irmc->buffer, "Total-Records:%d\r\n"
				"Maximum-Records:%d\r\n"
				"IEL:2\r\n"
				"DID:%s\r\n",
				irmc->params->maxlistcount,
				irmc->params->maxlistcount, irmc->did);

	return 0;
}

static int irmc_open_cc(struct irmc_session *irmc)
{
	if (irmc->buffer == NULL)
		irmc->buffer = g_string_new("");

	g_string_printf(irmc->buffer, "%d\r\n", irmc->params->maxlistcount);

	return 0;
}

static int irmc_open_cal(struct irmc_session *irmc)
{
	/* no suport yet. Just return an empty buffer. cal.vcs */
	DBG("unsupported, returning empty buffer");

	if (!irmc->buffer)
		irmc->buffer = g_string_new("");

	return 0;
}

static int irmc_open_nt(struct irmc_session *irmc)
{
	/* no suport yet. Just return an empty buffer. nt.vnt */
	DBG("unsupported, returning empty buffer");

	if (!irmc->buffer)
		irmc->buffer = g_string_new("");

	return 0;
}

static int irmc_open_luid(struct irmc_session *irmc)
{
	if (irmc->buffer == NULL)
		irmc->buffer = g_string_new("");

	DBG("changelog request, force whole book");
	g_string_printf(irmc->buffer, "SN:%s\r\n"
					"DID:%s\r\n"
					"Total-Records:%d\r\n"
					"Maximum-Records:%d\r\n"
					"*\r\n",
					irmc->sn, irmc->did,
					irmc->params->maxlistcount,
					irmc->params->maxlistcount);

	return 0;
}

static void *irmc_open(const char *name, int oflag, mode_t mode, void *context,
							size_t *size, int *err)
{
	struct irmc_session *irmc = context;
	int ret = 0;
	char *path;

	DBG("name %s context %p", name, context);

	if (oflag != O_RDONLY) {
		ret = -EPERM;
		goto fail;
	}

	if (name == NULL) {
		ret = -EBADR;
		goto fail;
	}

	/* Always contains the absolute path */
	if (g_path_is_absolute(name))
		path = g_strdup(name);
	else
		path = g_build_filename("/", name, NULL);

	if (g_str_equal(path, PB_DEVINFO))
		ret = irmc_open_devinfo(irmc);
	else if (g_str_equal(path, PB_CONTACTS))
		ret = irmc_open_pb(irmc);
	else if (g_str_equal(path, PB_INFO_LOG))
		ret = irmc_open_info(irmc);
	else if (g_str_equal(path, PB_CC_LOG))
		ret = irmc_open_cc(irmc);
	else if (g_str_has_prefix(path, PB_CALENDAR_FOLDER))
		ret = irmc_open_cal(irmc);
	else if (g_str_has_prefix(path, PB_NOTES_FOLDER))
		ret = irmc_open_nt(irmc);
	else if (g_str_has_prefix(path, PB_LUID_FOLDER))
		ret = irmc_open_luid(irmc);
	else
		ret = -EBADR;

	g_free(path);

	if (ret == 0)
		return irmc;

fail:
	if (err)
		*err = ret;

	return NULL;
}

static int irmc_close(void *object)
{
	struct irmc_session *irmc = object;

	DBG("");

	if (irmc->buffer) {
		g_string_free(irmc->buffer, TRUE);
		irmc->buffer = NULL;
	}

	if (irmc->request) {
		phonebook_req_finalize(irmc->request);
		irmc->request = NULL;
	}

	return 0;
}

static ssize_t irmc_read(void *object, void *buf, size_t count)
{
	struct irmc_session *irmc = object;
	int len;

	DBG("buffer %p count %zu", irmc->buffer, count);
	if (!irmc->buffer)
                return -EAGAIN;

	len = string_read(irmc->buffer, buf, count);
	DBG("returning %d bytes", len);
	return len;
}

static struct obex_mime_type_driver irmc_driver = {
	.target = IRMC_TARGET,
	.target_size = IRMC_TARGET_SIZE,
	.open = irmc_open,
	.close = irmc_close,
	.read = irmc_read,
};

static struct obex_service_driver irmc = {
	.name = "IRMC Sync server",
	.service = OBEX_IRMC,
	.target = IRMC_TARGET,
	.target_size = IRMC_TARGET_SIZE,
	.connect = irmc_connect,
	.get = irmc_get,
	.disconnect = irmc_disconnect,
	.chkput = irmc_chkput
};

static int irmc_init(void)
{
	int err;

	DBG("");
	err = phonebook_init();
	if (err < 0)
		return err;

	err = obex_mime_type_driver_register(&irmc_driver);
	if (err < 0)
		goto fail_mime_irmc;

	err = obex_service_driver_register(&irmc);
	if (err < 0)
		goto fail_irmc_reg;

	return 0;

fail_irmc_reg:
	obex_mime_type_driver_unregister(&irmc_driver);
fail_mime_irmc:
	phonebook_exit();

	return err;
}

static void irmc_exit(void)
{
	DBG("");
	obex_service_driver_unregister(&irmc);
	obex_mime_type_driver_unregister(&irmc_driver);
	phonebook_exit();
}

OBEX_PLUGIN_DEFINE(irmc, irmc_init, irmc_exit)
