/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2007-2013  Intel Corporation. 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 version 2 as
 *  published by the Free Software Foundation.
 *
 *  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 <sys/time.h>

#include <gdbus.h>

#include "connman.h"

enum timezone_updates {
	TIMEZONE_UPDATES_UNKNOWN = 0,
	TIMEZONE_UPDATES_MANUAL  = 1,
	TIMEZONE_UPDATES_AUTO    = 2,
};

static enum time_updates time_updates_config = TIME_UPDATES_AUTO;
static enum timezone_updates timezone_updates_config = TIMEZONE_UPDATES_AUTO;

static char *timezone_config = NULL;

static const char *time_updates2string(enum time_updates value)
{
	switch (value) {
	case TIME_UPDATES_UNKNOWN:
		break;
	case TIME_UPDATES_MANUAL:
		return "manual";
	case TIME_UPDATES_AUTO:
		return "auto";
	}

	return NULL;
}

static enum time_updates string2time_updates(const char *value)
{
	if (g_strcmp0(value, "manual") == 0)
		return TIME_UPDATES_MANUAL;
	else if (g_strcmp0(value, "auto") == 0)
		return TIME_UPDATES_AUTO;

	return TIME_UPDATES_UNKNOWN;
}

static const char *timezone_updates2string(enum timezone_updates value)
{
	switch (value) {
	case TIMEZONE_UPDATES_UNKNOWN:
		break;
	case TIMEZONE_UPDATES_MANUAL:
		return "manual";
	case TIMEZONE_UPDATES_AUTO:
		return "auto";
	}

	return NULL;
}

static enum timezone_updates string2timezone_updates(const char *value)
{
	if (g_strcmp0(value, "manual") == 0)
		return TIMEZONE_UPDATES_MANUAL;
	else if (g_strcmp0(value, "auto") == 0)
		return TIMEZONE_UPDATES_AUTO;

        return TIMEZONE_UPDATES_UNKNOWN;
}

static void clock_properties_load(void)
{
	GKeyFile *keyfile;
	char *str;
	enum time_updates time_value;
	enum timezone_updates timezone_value;

	keyfile = __connman_storage_load_global();
	if (!keyfile)
		return;

	str = g_key_file_get_string(keyfile, "global", "TimeUpdates", NULL);

	time_value = string2time_updates(str);
	if (time_value != TIME_UPDATES_UNKNOWN)
		time_updates_config = time_value;

	g_free(str);

	str = g_key_file_get_string(keyfile, "global", "TimezoneUpdates",
			NULL);

	timezone_value = string2timezone_updates(str);
	if (timezone_value != TIMEZONE_UPDATES_UNKNOWN)
		timezone_updates_config = timezone_value;

	g_free(str);

	g_key_file_free(keyfile);
}

static void clock_properties_save(void)
{
	GKeyFile *keyfile;
	const char *str;

	keyfile = __connman_storage_load_global();
	if (!keyfile)
		keyfile = g_key_file_new();

	str = time_updates2string(time_updates_config);
	if (str)
		g_key_file_set_string(keyfile, "global", "TimeUpdates", str);
	else
		g_key_file_remove_key(keyfile, "global", "TimeUpdates", NULL);

	str = timezone_updates2string(timezone_updates_config);
	if (str)
		g_key_file_set_string(keyfile, "global", "TimezoneUpdates",
				str);
	else
		g_key_file_remove_key(keyfile, "global", "TimezoneUpdates",
				NULL);

	__connman_storage_save_global(keyfile);

	g_key_file_free(keyfile);
}

enum time_updates __connman_clock_timeupdates(void)
{
	return time_updates_config;
}

static void append_timeservers(DBusMessageIter *iter, void *user_data)
{
	int i;
	char **timeservers = __connman_timeserver_system_get();

	if (!timeservers)
		return;

	for (i = 0; timeservers[i]; i++) {
		dbus_message_iter_append_basic(iter,
				DBUS_TYPE_STRING, &timeservers[i]);
	}

	g_strfreev(timeservers);
}

static DBusMessage *get_properties(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	DBusMessageIter array, dict;
	dbus_bool_t is_synced;
	struct timeval tv;
	const char *str;

	DBG("conn %p", conn);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return NULL;

	dbus_message_iter_init_append(reply, &array);

	connman_dbus_dict_open(&array, &dict);

	if (gettimeofday(&tv, NULL) == 0) {
		dbus_uint64_t val = tv.tv_sec;

		connman_dbus_dict_append_basic(&dict, "Time",
						DBUS_TYPE_UINT64, &val);
	}

	str = time_updates2string(time_updates_config);
	if (str)
		connman_dbus_dict_append_basic(&dict, "TimeUpdates",
						DBUS_TYPE_STRING, &str);

	if (timezone_config)
		connman_dbus_dict_append_basic(&dict, "Timezone",
					DBUS_TYPE_STRING, &timezone_config);

	str = timezone_updates2string(timezone_updates_config);
	if (str)
		connman_dbus_dict_append_basic(&dict, "TimezoneUpdates",
						DBUS_TYPE_STRING, &str);

	connman_dbus_dict_append_array(&dict, "Timeservers",
				DBUS_TYPE_STRING, append_timeservers, NULL);

	is_synced = __connman_timeserver_is_synced();
	connman_dbus_dict_append_basic(&dict, "TimeserverSynced",
					DBUS_TYPE_BOOLEAN, &is_synced);

	connman_dbus_dict_close(&array, &dict);

	return reply;
}

static DBusMessage *set_property(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	DBusMessageIter iter, value;
	const char *name;
	int type;

	DBG("conn %p", conn);

	if (!dbus_message_iter_init(msg, &iter))
		return __connman_error_invalid_arguments(msg);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
		return __connman_error_invalid_arguments(msg);

	dbus_message_iter_get_basic(&iter, &name);
	dbus_message_iter_next(&iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
		return __connman_error_invalid_arguments(msg);

	dbus_message_iter_recurse(&iter, &value);

	type = dbus_message_iter_get_arg_type(&value);

	if (g_str_equal(name, "Time")) {
		struct timeval tv;
		dbus_uint64_t newval;

		if (type != DBUS_TYPE_UINT64)
			return __connman_error_invalid_arguments(msg);

		if (time_updates_config != TIME_UPDATES_MANUAL)
			return __connman_error_permission_denied(msg);

		dbus_message_iter_get_basic(&value, &newval);

		tv.tv_sec = newval;
		tv.tv_usec = 0;

		if (settimeofday(&tv, NULL) < 0)
			return __connman_error_invalid_arguments(msg);

		__connman_timeserver_set_synced(false);
		connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
				CONNMAN_CLOCK_INTERFACE, "Time",
				DBUS_TYPE_UINT64, &newval);
	} else if (g_str_equal(name, "TimeUpdates")) {
		const char *strval;
		enum time_updates newval;

		if (type != DBUS_TYPE_STRING)
			return __connman_error_invalid_arguments(msg);

		dbus_message_iter_get_basic(&value, &strval);
		newval = string2time_updates(strval);

		if (newval == TIME_UPDATES_UNKNOWN)
			return __connman_error_invalid_arguments(msg);

		if (newval == time_updates_config)
			return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);

		time_updates_config = newval;

		clock_properties_save();
		connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
				CONNMAN_CLOCK_INTERFACE, "TimeUpdates",
				DBUS_TYPE_STRING, &strval);

		if (newval == TIME_UPDATES_AUTO) {
			struct connman_service *service;

			service = connman_service_get_default();
			__connman_timeserver_conf_update(service);
		}
	} else if (g_str_equal(name, "Timezone")) {
		const char *strval;

		if (type != DBUS_TYPE_STRING)
			return __connman_error_invalid_arguments(msg);

		if (timezone_updates_config != TIMEZONE_UPDATES_MANUAL)
			return __connman_error_permission_denied(msg);

		dbus_message_iter_get_basic(&value, &strval);

		if (__connman_timezone_change(strval) < 0)
			return __connman_error_invalid_arguments(msg);
	} else if (g_str_equal(name, "TimezoneUpdates")) {
		const char *strval;
		enum timezone_updates newval;

		if (type != DBUS_TYPE_STRING)
			return __connman_error_invalid_arguments(msg);

		dbus_message_iter_get_basic(&value, &strval);
		newval = string2timezone_updates(strval);

		if (newval == TIMEZONE_UPDATES_UNKNOWN)
			return __connman_error_invalid_arguments(msg);

		if (newval == timezone_updates_config)
			return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);

		timezone_updates_config = newval;

		clock_properties_save();
		connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
				CONNMAN_CLOCK_INTERFACE, "TimezoneUpdates",
				DBUS_TYPE_STRING, &strval);
	} else if (g_str_equal(name, "Timeservers")) {
		DBusMessageIter entry;
		char **str = NULL;
		GSList *list = NULL;
		int count = 0;

		if (type != DBUS_TYPE_ARRAY)
			return __connman_error_invalid_arguments(msg);

		dbus_message_iter_recurse(&value, &entry);

		while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
			const char *val;
			GSList *new_head;

			dbus_message_iter_get_basic(&entry, &val);

			new_head = __connman_timeserver_add_list(list, val);
			if (list != new_head) {
				count++;
				list = new_head;
			}

			dbus_message_iter_next(&entry);
		}

		if (list) {
			str = g_new0(char *, count+1);

			while (list) {
				count--;
				str[count] = list->data;
				list = g_slist_delete_link(list, list);
			};
		}

		__connman_timeserver_system_set(str);

		if (str)
			g_strfreev(str);

		connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
				CONNMAN_CLOCK_INTERFACE, "Timeservers",
				DBUS_TYPE_STRING, append_timeservers, NULL);
	} else if (g_str_equal(name, "TimeserverSynced")) {
		return __connman_error_permission_denied(msg);
	} else
		return __connman_error_invalid_property(msg);

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

static const GDBusMethodTable clock_methods[] = {
	{ GDBUS_METHOD("GetProperties",
			NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
			get_properties) },
	{ GDBUS_METHOD("SetProperty",
			GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
			set_property)   },
	{ },
};

static const GDBusSignalTable clock_signals[] = {
	{ GDBUS_SIGNAL("PropertyChanged",
			GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
	{ },
};

static DBusConnection *connection = NULL;

void __connman_clock_update_timezone(void)
{
	DBG("");

	g_free(timezone_config);
	timezone_config = __connman_timezone_lookup();

	if (!timezone_config)
		return;

	connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
				CONNMAN_CLOCK_INTERFACE, "Timezone",
				DBUS_TYPE_STRING, &timezone_config);
}

int __connman_clock_init(void)
{
	DBG("");

	connection = connman_dbus_get_connection();
	if (!connection)
		return -1;

	__connman_timezone_init();

	timezone_config = __connman_timezone_lookup();

	g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
						CONNMAN_CLOCK_INTERFACE,
						clock_methods, clock_signals,
						NULL, NULL, NULL);

	clock_properties_load();
	return 0;
}

void __connman_clock_cleanup(void)
{
	DBG("");

	if (!connection)
		return;

	g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
						CONNMAN_CLOCK_INTERFACE);

	dbus_connection_unref(connection);

	__connman_timezone_cleanup();

	g_free(timezone_config);
}
