/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2007-2012  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 <glib.h>

#include "connman.h"

static unsigned int next_lookup_token = 1;

static GSList *driver_list = NULL;
static GSList *lookup_list = NULL;

struct proxy_lookup {
	unsigned int token;
	connman_proxy_lookup_cb cb;
	void *user_data;
	struct connman_service *service;
	char *url;
	guint watch;
	struct connman_proxy_driver *proxy;
};

static void remove_lookup(struct proxy_lookup *lookup)
{
	lookup_list = g_slist_remove(lookup_list, lookup);

	connman_service_unref(lookup->service);
	g_free(lookup->url);
	g_free(lookup);
}

static void remove_lookups(GSList *lookups)
{
	GSList *list;

	for (list = lookups; list; list = list->next) {
		struct proxy_lookup *lookup = list->data;

		remove_lookup(lookup);
	}

	g_slist_free(lookups);
}

static gboolean lookup_callback(gpointer user_data)
{
	struct proxy_lookup *lookup = user_data;
	GSList *list;

	if (lookup == NULL)
		return FALSE;

	lookup->watch = 0;

	for (list = driver_list; list; list = list->next) {
		struct connman_proxy_driver *proxy = list->data;

		if (proxy->request_lookup == NULL)
			continue;

		lookup->proxy = proxy;
		break;
	}

	if (lookup->proxy == NULL ||
		lookup->proxy->request_lookup(lookup->service,
						lookup->url) < 0) {

		if (lookup->cb)
			lookup->cb(NULL, lookup->user_data);

		remove_lookup(lookup);
	}

	return FALSE;
}

unsigned int connman_proxy_lookup(const char *interface, const char *url,
					struct connman_service *service,
					connman_proxy_lookup_cb cb,
					void *user_data)
{
	struct proxy_lookup *lookup;

	DBG("interface %s url %s", interface, url);

	if (interface == NULL)
		return 0;

	lookup = g_try_new0(struct proxy_lookup, 1);
	if (lookup == NULL)
		return 0;

	lookup->token = next_lookup_token++;

	lookup->cb = cb;
	lookup->user_data = user_data;
	lookup->url = g_strdup(url);
	lookup->service = connman_service_ref(service);

	lookup->watch = g_timeout_add_seconds(0, lookup_callback, lookup);
	if (lookup->watch == 0) {
		g_free(lookup->url);
		g_free(lookup);
		return 0;
	}

	DBG("token %u", lookup->token);
	lookup_list = g_slist_prepend(lookup_list, lookup);

	return lookup->token;
}

void connman_proxy_lookup_cancel(unsigned int token)
{
	GSList *list;
	struct proxy_lookup *lookup = NULL;

	DBG("token %u", token);

	for (list = lookup_list; list; list = list->next) {
		lookup = list->data;

		if (lookup->token == token)
			break;

		lookup = NULL;
	}

	if (lookup != NULL) {
		if (lookup->watch > 0) {
			g_source_remove(lookup->watch);
			lookup->watch = 0;
		}

		if (lookup->proxy != NULL &&
					lookup->proxy->cancel_lookup != NULL)
			lookup->proxy->cancel_lookup(lookup->service,
								lookup->url);

		remove_lookup(lookup);
	}
}

void connman_proxy_driver_lookup_notify(struct connman_service *service,
                                        const char *url, const char *result)
{
	GSList *list, *matches = NULL;

	DBG("service %p url %s result %s", service, url, result);

	for (list = lookup_list; list; list = list->next) {
		struct proxy_lookup *lookup = list->data;

		if (service != lookup->service)
			continue;

		if (g_strcmp0(lookup->url, url) == 0) {
			if (lookup->cb)
				lookup->cb(result, lookup->user_data);

			matches = g_slist_prepend(matches, lookup);
		}
	}

	if (matches != NULL)
		remove_lookups(matches);
}

static gint compare_priority(gconstpointer a, gconstpointer b)
{
	const struct connman_proxy_driver *driver1 = a;
	const struct connman_proxy_driver *driver2 = b;

	return driver2->priority - driver1->priority;
}

/**
 * connman_proxy_driver_register:
 * @driver: Proxy driver definition
 *
 * Register a new proxy driver
 *
 * Returns: %0 on success
 */
int connman_proxy_driver_register(struct connman_proxy_driver *driver)
{
	DBG("driver %p name %s", driver, driver->name);

	driver_list = g_slist_insert_sorted(driver_list, driver,
							compare_priority);

	return 0;
}

/**
 * connman_proxy_driver_unregister:
 * @driver: Proxy driver definition
 *
 * Remove a previously registered proxy driver
 */
void connman_proxy_driver_unregister(struct connman_proxy_driver *driver)
{
	GSList *list;

	DBG("driver %p name %s", driver, driver->name);

	driver_list = g_slist_remove(driver_list, driver);

	for (list = lookup_list; list; list = list->next) {
		struct proxy_lookup *lookup = list->data;

		if (lookup->proxy == driver)
			lookup->proxy = NULL;
	}

}

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

	return 0;
}

void __connman_proxy_cleanup(void)
{
	DBG("");

	remove_lookups(lookup_list);
}
