/*
 *
 *  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 <errno.h>

#include <glib.h>
#include <stdlib.h>
#include <gweb/gresolv.h>
#include <netdb.h>

#include <gdhcp/timer.h>

#include "connman.h"

#undef DBG
#define DBG(msg, ...) connman_info("ntp: " msg, ##__VA_ARGS__)

// fail-safe for non-linux builds
#ifndef CLOCK_BOOTTIME
#define CLOCK_BOOTTIME CLOCK_REALTIME
#endif

#define TS_RECHECK_INTERVAL     7200

static GSList *ts_list = NULL;
static char *ts_current = NULL;
static int ts_recheck_id = 0;

static GResolv *resolv = NULL;
static int resolv_id = 0;

static void resolv_debug(const char *str, void *data)
{
	connman_info("%s: %s\n", (const char *) data, str);
}
static void save_timeservers(char **servers)
{
	GKeyFile *keyfile;
	int cnt;

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

	for (cnt = 0; servers && servers[cnt]; cnt++);

	g_key_file_set_string_list(keyfile, "global", "Timeservers",
			   (const gchar **)servers, cnt);

	__connman_storage_save_global(keyfile);

	g_key_file_free(keyfile);

	return;
}

static char **load_timeservers(void)
{
	GKeyFile *keyfile;
	char **servers = NULL;

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

	servers = g_key_file_get_string_list(keyfile, "global",
						"Timeservers", NULL, NULL);

	g_key_file_free(keyfile);

	return servers;
}

static void resolv_result(GResolvResultStatus status, char **results,
				gpointer user_data)
{
	int i;

	DBG("status %d", status);

	if (status == G_RESOLV_RESULT_STATUS_SUCCESS) {
		if (results) {
			for (i = 0; results[i]; i++) {
				DBG("result[%d]: %s", i, results[i]);
				if (i == 0)
					continue;

				ts_list = __connman_timeserver_add_list(
							ts_list, results[i]);
			}

			DBG("Using timeserver %s", results[0]);

			__connman_ntp_start(results[0]);

			return;
		}
	}

	/* If resolving fails, move to the next server */
	__connman_timeserver_sync_next();
}

/*
 * Once the timeserver list (ts_list) is created, we start querying the
 * servers one by one. If resolving fails on one of them, we move to the
 * next one. The user can enter either an IP address or a URL for the
 * timeserver. We only resolve the URLs. Once we have an IP for the NTP
 * server, we start querying it for time corrections.
 */
void __connman_timeserver_sync_next()
{
	if (ts_current) {
		g_free(ts_current);
		ts_current = NULL;
	}

	__connman_ntp_stop();

	/* Get the 1st server in the list */
	if (!ts_list)
		return;

	ts_current = ts_list->data;

	ts_list = g_slist_delete_link(ts_list, ts_list);

	/* if it's an IP, directly query it. */
	if (connman_inet_check_ipaddress(ts_current) > 0) {
		DBG("Using timeserver %s", ts_current);

		__connman_ntp_start(ts_current);

		return;
	}

	DBG("Resolving timeserver %s", ts_current);

	resolv_id = g_resolv_lookup_hostname(resolv, ts_current,
						resolv_result, NULL);

	return;
}

GSList *__connman_timeserver_add_list(GSList *server_list,
		const char *timeserver)
{
	GSList *list = server_list;

	if (!timeserver)
		return server_list;

	while (list) {
		char *existing_server = list->data;
		if (strcmp(timeserver, existing_server) == 0)
			return server_list;
		list = g_slist_next(list);
	}
	return g_slist_prepend(server_list, g_strdup(timeserver));
}

/*
 * __connman_timeserver_get_all function creates the timeserver
 * list which will be used to determine NTP server for time corrections.
 * The service settings take priority over the global timeservers.
 */
GSList *__connman_timeserver_get_all(struct connman_service *service)
{
	GSList *list = NULL;
	struct connman_network *network;
	char **timeservers;
	char **service_ts;
	char **service_ts_config;
	char **fallback_ts;
	int i;

	if (__connman_clock_timeupdates() == TIME_UPDATES_MANUAL)
		return NULL;

	service_ts_config = connman_service_get_timeservers_config(service);

	/* First add Service Timeservers.Configuration to the list */
	for (i = 0; service_ts_config && service_ts_config[i];
			i++)
		list = __connman_timeserver_add_list(list,
				service_ts_config[i]);

	service_ts = connman_service_get_timeservers(service);

	if (connman_setting_get_bool("PreferFallbackTimeservers")) {
		/* Only add the fallback servers */

		fallback_ts = connman_setting_get_string_list("FallbackTimeservers");

		for (i = 0; fallback_ts && fallback_ts[i]; i++)
			list = __connman_timeserver_add_list(list, fallback_ts[i]);

		if (i)
			return g_slist_reverse(list);

		connman_info("ntp: no fallback servers , ignoring preference");
	}

	/* Then add Service Timeservers via DHCP to the list */
	for (i = 0; service_ts && service_ts[i]; i++)
		list = __connman_timeserver_add_list(list, service_ts[i]);

	/* Then add Global Timeservers to the list */
	timeservers = load_timeservers();

	for (i = 0; timeservers && timeservers[i]; i++)
		list = __connman_timeserver_add_list(list, timeservers[i]);

	g_strfreev(timeservers);

	fallback_ts = connman_setting_get_string_list("FallbackTimeservers");

	/* Lastly add the fallback servers */
	for (i = 0; fallback_ts && fallback_ts[i]; i++)
		list = __connman_timeserver_add_list(list, fallback_ts[i]);

	return g_slist_reverse(list);
}

static gboolean ts_recheck(gpointer user_data)
{
	GSList *ts;

	ts = __connman_timeserver_get_all(__connman_service_get_default());

	if (!ts) {
		DBG("timeservers disabled");

		return TRUE;
	}

	if (g_strcmp0(ts_current, ts->data) != 0) {
		DBG("current %s preferred %s", ts_current, (char *)ts->data);

		g_slist_free_full(ts, g_free);

		__connman_timeserver_sync(NULL);

		return FALSE;
	}

	DBG("recheck rearm");

	g_slist_free_full(ts, g_free);

	return TRUE;
}

static void ts_recheck_disable(void)
{
	if (ts_recheck_id == 0)
		return;

	g_rttimeout_source_remove(ts_recheck_id);
	ts_recheck_id = 0;

	if (ts_current) {
		g_free(ts_current);
		ts_current = NULL;
	}
}

static void ts_recheck_enable(void)
{
	if (ts_recheck_id > 0)
		return;

	ts_recheck_id = g_rttimeout_add_seconds_full(CLOCK_BOOTTIME, G_PRIORITY_DEFAULT,
		TS_RECHECK_INTERVAL, ts_recheck, NULL, NULL);
}

/*
 * This function must be called everytime the default service changes, the
 * service timeserver(s) or gateway changes or the global timeserver(s) changes.
 */
int __connman_timeserver_sync(struct connman_service *default_service)
{
	struct connman_service *service;
	enum connman_service_type service_type;

	if (default_service)
		service = default_service;
	else
		service = __connman_service_get_default();

	service_type = connman_service_get_type(service);

	DBG("sync in_service=%p service=%p type=%d", default_service, service, service_type);

	switch (service_type) {
	case CONNMAN_SERVICE_TYPE_UNKNOWN:
	case CONNMAN_SERVICE_TYPE_LOWPAN:
		return -EINVAL;
	default:
		break;
	}

	if (!resolv)
		return 0;
	/*
	 * Before we start creating the new timeserver list we must stop
	 * any ongoing ntp query and server resolution.
	 */

	__connman_ntp_stop();

	ts_recheck_disable();

	if (resolv_id > 0)
		g_resolv_cancel_lookup(resolv, resolv_id);

	g_slist_free_full(ts_list, g_free);

	ts_list = __connman_timeserver_get_all(service);

	__connman_service_timeserver_changed(service, ts_list);

	if (!ts_list) {
		DBG("No timeservers set.");
		return 0;
	}

	ts_recheck_enable();

	__connman_timeserver_sync_next();

	return 0;
}

static int timeserver_update_resolver(struct connman_service *service)
{
	enum connman_service_type service_type;
	char **nameservers;
	int i;
	GSList *list;

	service_type = connman_service_get_type(service);

	DBG("update resolver service=%p type=%d", service, service_type);

	switch (service_type) {
	case CONNMAN_SERVICE_TYPE_UNKNOWN:
	case CONNMAN_SERVICE_TYPE_LOWPAN:
		return -EINVAL;
	default:
		break;
	}

	i = __connman_service_get_index(service);
	if (i < 0)
		return -EINVAL;

	/* Don't enable timeserver resolver if time server is not configured */
	list = __connman_timeserver_get_all(service);
	if (!list)
		return -EINVAL;
	g_slist_free_full(list, g_free);

	nameservers = connman_service_get_nameservers(service);
	if (!nameservers)
		return -EINVAL;

	/* Stop an already ongoing resolution, if there is one */
	if (resolv && resolv_id > 0)
		g_resolv_cancel_lookup(resolv, resolv_id);

	/* get rid of the old resolver */
	if (resolv) {
		g_resolv_unref(resolv);
		resolv = NULL;
	}

	resolv = g_resolv_new(i);
	if (!resolv) {
		g_strfreev(nameservers);
		return -ENOMEM;
	}

	/* turn on NTP resolver debug */
	g_resolv_set_debug(resolv, resolv_debug, "NtpRes");

	for (i = 0; nameservers[i]; i++)
		g_resolv_add_nameserver(resolv, nameservers[i], 53, 0);

	g_strfreev(nameservers);

	return 0;
}

static int timeserver_start(struct connman_service *service)
{
	DBG("service %p", service);

	int ret = timeserver_update_resolver(service);
	if (ret == 0)
		ret = __connman_timeserver_sync(service);
	return ret;
}

static void timeserver_stop(void)
{
	DBG(" ");

	if (resolv) {
		g_resolv_unref(resolv);
		resolv = NULL;
	}

	g_slist_free_full(ts_list, g_free);

	ts_list = NULL;

	__connman_ntp_stop();

	ts_recheck_disable();
}

void __connman_timeserver_resync(struct connman_service *service)
{
	if (timeserver_update_resolver(service) == 0 && !__connman_ntp_check_started())
		__connman_timeserver_sync(service);
}

int __connman_timeserver_system_set(char **servers)
{
	save_timeservers(servers);

	__connman_timeserver_sync(NULL);

	return 0;
}

char **__connman_timeserver_system_get()
{
	char **servers;

	servers = load_timeservers();
	return servers;
}

static void default_changed(struct connman_service *default_service)
{
	if (default_service)
		timeserver_start(default_service);
	else
		timeserver_stop();
}

static struct connman_notifier timeserver_notifier = {
	.name			= "timeserver",
	.default_changed	= default_changed,
};

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

	connman_notifier_register(&timeserver_notifier);

	return 0;
}

void __connman_timeserver_cleanup(void)
{
	DBG("");

	connman_notifier_unregister(&timeserver_notifier);
}
