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

#include <gweb/gweb.h>

#include "connman.h"

#define STATUS_URL_IPV4  "http://ipv4.connman.net/online/status.html"
#define STATUS_URL_IPV6  "http://ipv6.connman.net/online/status.html"

#define STATUS_URL_GOOGLE  "http://clients3.google.com/generate_204"

struct connman_wispr_message {
	bool has_error;
	const char *current_element;
	int message_type;
	int response_code;
	char *login_url;
	char *abort_login_url;
	char *logoff_url;
	char *access_procedure;
	char *access_location;
	char *location_name;
};

enum connman_wispr_result {
	CONNMAN_WISPR_RESULT_UNKNOWN = 0,
	CONNMAN_WISPR_RESULT_LOGIN   = 1,
	CONNMAN_WISPR_RESULT_ONLINE  = 2,
	CONNMAN_WISPR_RESULT_FAILED  = 3,
};

struct wispr_route {
	char *address;
	int if_index;
};

struct connman_wispr_portal_context {
	struct connman_service *service;
	enum connman_ipconfig_type type;
	struct connman_wispr_portal *wispr_portal;

	/* Portal/WISPr common */
	GWeb *web;
	unsigned int token;
	guint request_id;

	const char *status_url;

	char *redirect_url;

	/* WISPr specific */
	GWebParser *wispr_parser;
	struct connman_wispr_message wispr_msg;

	char *wispr_username;
	char *wispr_password;
	char *wispr_formdata;

	enum connman_wispr_result wispr_result;

	GSList *route_list;

	guint timeout;
	guint oc_timeout; /* online check timeout */
	enum connman_wispr_server wispr_server;
	GWebResultFunc wispr_result_func;
};

struct connman_wispr_portal {
	struct connman_wispr_portal_context *ipv4_context;
	struct connman_wispr_portal_context *ipv6_context;
};

static bool wispr_portal_web_result_connman(GWebResult *result, gpointer user_data);
static bool wispr_portal_web_result_google(GWebResult *result, gpointer user_data);
static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context);
static gboolean wispr_schedule_pendings(gpointer user_data);

static GHashTable *wispr_portal_list = NULL;
GSList *wispr_pending=NULL;
guint wispr_pending_timeout=0;


static void connman_wispr_message_init(struct connman_wispr_message *msg)
{
	DBG("");

	msg->has_error = false;
	msg->current_element = NULL;

	msg->message_type = -1;
	msg->response_code = -1;

	g_free(msg->login_url);
	msg->login_url = NULL;

	g_free(msg->abort_login_url);
	msg->abort_login_url = NULL;

	g_free(msg->logoff_url);
	msg->logoff_url = NULL;

	g_free(msg->access_procedure);
	msg->access_procedure = NULL;

	g_free(msg->access_location);
	msg->access_location = NULL;

	g_free(msg->location_name);
	msg->location_name = NULL;
}

static void free_wispr_routes(struct connman_wispr_portal_context *wp_context)
{
	while (wp_context->route_list) {
		struct wispr_route *route = wp_context->route_list->data;

		DBG("free route to %s if %d type %d", route->address,
				route->if_index, wp_context->type);

		switch (wp_context->type) {
		case CONNMAN_IPCONFIG_TYPE_IPV4:
			connman_inet_del_host_route(route->if_index,
					route->address);
			break;
		case CONNMAN_IPCONFIG_TYPE_IPV6:
			connman_inet_del_ipv6_host_route(route->if_index,
					route->address);
			break;
		case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
		case CONNMAN_IPCONFIG_TYPE_ALL:
			break;
		}

		g_free(route->address);
		g_free(route);

		wp_context->route_list =
			g_slist_delete_link(wp_context->route_list,
					wp_context->route_list);
	}
}

#define ONLINE_CHECK_MAX_SECONDS 10

static void free_connman_wispr_portal_context(
		struct connman_wispr_portal_context *wp_context)
{
	DBG("context %p", wp_context);

	if (!wp_context)
		return;

	if (wp_context->wispr_portal) {
		if (wp_context->wispr_portal->ipv4_context == wp_context)
			wp_context->wispr_portal->ipv4_context = NULL;

		if (wp_context->wispr_portal->ipv6_context == wp_context)
			wp_context->wispr_portal->ipv6_context = NULL;
	}

	if (wp_context->token > 0)
		connman_proxy_lookup_cancel(wp_context->token);

	if (wp_context->request_id > 0)
		g_web_cancel_request(wp_context->web, wp_context->request_id);

	if (wp_context->timeout > 0)
		g_source_remove(wp_context->timeout);

	if (wp_context->oc_timeout > 0)
		g_source_remove(wp_context->oc_timeout);

	if (wp_context->web)
		g_web_unref(wp_context->web);

	g_free(wp_context->redirect_url);

	if (wp_context->wispr_parser)
		g_web_parser_unref(wp_context->wispr_parser);

	connman_wispr_message_init(&wp_context->wispr_msg);

	g_free(wp_context->wispr_username);
	g_free(wp_context->wispr_password);
	g_free(wp_context->wispr_formdata);

	free_wispr_routes(wp_context);

	g_free(wp_context);
}

static struct connman_wispr_portal_context *create_wispr_portal_context(void)
{
	return g_try_new0(struct connman_wispr_portal_context, 1);
}

static void wispr_stop(
		struct connman_wispr_portal_context *wp_context,
		int check_result, bool retry_pending)
{
	struct connman_service *service;
	enum connman_ipconfig_type type;

	DBG("context %p", wp_context);

	if (!wp_context)
		return;

	service = wp_context->service;
	type = wp_context->type;

	free_connman_wispr_portal_context(wp_context);

	if (((check_result == ONLINE_CHECK_FAIL) || (check_result == ONLINE_CHECK_DNS_FAIL)) &&
		(__connman_service_ipconfig_get_state(service, type) == CONNMAN_SERVICE_STATE_ONLINE)) {
		/* old state is online, but check failed */
		__connman_service_ipconfig_indicate_state(service, CONNMAN_SERVICE_STATE_READY, type);
	}

	if (check_result != ONLINE_CHECK_NO_RESULT) {
		__connman_service_online_check_stopped(service, wp_context, type, check_result);
	} else {
		OC_PRINT("check for context %p will use future result", wp_context);
	}

	if (retry_pending && wispr_pending) {
		DBG("setup timer to retry pending checks");
		if (wispr_pending_timeout)
			g_source_remove(wispr_pending_timeout);
		wispr_pending_timeout = g_timeout_add_seconds(0, wispr_schedule_pendings, NULL);
	}
}

/*
	Online check is independent of what default routing is set to. The independency is done by inserting
	one 	specific routing entry for the pair of target server ip address and routing interface. But if there are
	two simultaneous requests on different interface and check same online server. They will try to
	insert two routing entries with same destination ip. It will be a race which leads to unreliable check
	results. This check here is to guarantee there is only one request at a time for specific type (ipv4 vs ipv6)
	per interface.
*/
static bool wispr_allow_check(struct connman_wispr_portal *wispr_portal, enum connman_ipconfig_type type)
{
	GHashTableIter iter;
	gpointer key, value;

	DBG("wispr_portal %p", wispr_portal);

	g_hash_table_iter_init(&iter, wispr_portal_list);

	while (g_hash_table_iter_next(&iter, &key, &value)) {
		struct connman_wispr_portal *portal = value;

		/* Allow multiple checks on same interface */
		if (wispr_portal == portal)
			continue;

		if (((type == CONNMAN_IPCONFIG_TYPE_IPV4) && portal->ipv4_context) ||
			((type == CONNMAN_IPCONFIG_TYPE_IPV6) && portal->ipv6_context))
			return false;
	}

	return true;
}

static gboolean wispr_oc_timeout(gpointer user_data)
{
	struct connman_wispr_portal_context *wp_context = user_data;

	DBG("wp_context %p", wp_context);

	if (!wp_context)
		return false;

	wp_context->timeout = 0;

	wispr_stop(wp_context, ONLINE_CHECK_FAIL, true);

	return false;
}

static int wispr_start(struct connman_wispr_portal_context *wp_context, bool queue_only)
{
	DBG("wp_context %p", wp_context);

	if (!wp_context)
		return -ENOMEM;

	/* check if other interfaces are checking same type now */
	if (queue_only || !wispr_allow_check(wp_context->wispr_portal, wp_context->type)) {
		DBG("%s, put (%p %d) in pending queue", queue_only ? "Queue only" : "Cannot issue check now",
			wp_context->service, wp_context->type);
		connman_service_ref(wp_context->service);
		wispr_pending = g_slist_append(wispr_pending, wp_context);
		return 0;
	}

	/* If there is already an existing context, we wipe this new request */
	if (wp_context->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
		if (wp_context->wispr_portal->ipv4_context) {
			OC_PRINT("new ipv4 check context %p, ongoing %p",
				wp_context, wp_context->wispr_portal->ipv4_context);
			return -EALREADY;
		}
		wp_context->wispr_portal->ipv4_context = wp_context;
	} else if (wp_context->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
		if (wp_context->wispr_portal->ipv6_context) {
			OC_PRINT("new ipv6 check context %p, ongoing %p",
				wp_context, wp_context->wispr_portal->ipv6_context);
			return -EALREADY;
		}
		wp_context->wispr_portal->ipv6_context = wp_context;
	} else {
		OC_PRINT("invalid type %d", wp_context->type);
		return -EINVAL;
	}

	__connman_service_online_check_started(wp_context->service, wp_context, wp_context->type);

	if (wp_context->oc_timeout) {
		OC_PRINT("Ongoing check???");
		g_source_remove(wp_context->oc_timeout);
	}
	wp_context->oc_timeout = g_timeout_add_seconds(ONLINE_CHECK_MAX_SECONDS, wispr_oc_timeout, wp_context);

	return wispr_portal_detect(wp_context);
}

static gboolean wispr_schedule_pendings(gpointer user_data)
{
	GSList *last_list = NULL, *list;

	DBG("wispr_pending %p", wispr_pending);

	wispr_pending_timeout = 0;

	if (!wispr_pending)
		return false;

	last_list = g_slist_last(wispr_pending);
	while ((list = wispr_pending)) {
		struct connman_wispr_portal_context *context = list->data;

		if (context) {
			bool free_wp_context = true;
			int refcount = -1, check_result = ONLINE_CHECK_FAIL;
			if (context->service) {
				refcount = __connman_service_get_refcount(context->service) - 1;
				connman_service_unref(context->service);
				if (refcount > 0) {
					int ret = wispr_start(context, false);
					if (ret == 0)
						free_wp_context = false;
					else if (ret == -EALREADY)
						check_result = ONLINE_CHECK_NO_RESULT; // silent free context without notifying calller
				}
			}
			if (free_wp_context) {
				DBG("service %p, refcount %d, free context %p check_result %d",
					context->service, refcount, context, check_result);
				wispr_stop(context, check_result, false);
			}
		}

		wispr_pending = g_slist_delete_link(wispr_pending, list);

		if (list == last_list)
			break;
	}

	DBG("retry done");

	return false;
}

static void wispr_cleanup_pendings(gpointer user_data)
{
	GSList *next_list, *list;
	struct connman_service *service = (struct connman_service *)user_data;

	DBG("wispr_pending %p", wispr_pending);

	list = wispr_pending;
	while (list) {
		struct connman_wispr_portal_context *context = list->data;
		bool delete_list = false;

		next_list = g_slist_next(list);

		if (context) {
			if (!service || (service == context->service)) {
				if (context->service)
					connman_service_unref(context->service);
				wispr_stop(context, ONLINE_CHECK_FAIL, false);
				delete_list = true;
			}
		} else {
			delete_list = true;
		}

		if (delete_list)
			wispr_pending = g_slist_delete_link(wispr_pending, list);

		list = next_list;
	}

	DBG("remove done");
}

static void free_connman_wispr_portal(gpointer data)
{
	struct connman_wispr_portal *wispr_portal = data;

	DBG("");

	if (!wispr_portal)
		return;

	wispr_stop(wispr_portal->ipv4_context, ONLINE_CHECK_FAIL, false);
	wispr_stop(wispr_portal->ipv6_context, ONLINE_CHECK_FAIL, true);

	g_free(wispr_portal);
}

static const char *message_type_to_string(int message_type)
{
	switch (message_type) {
	case 100:
		return "Initial redirect message";
	case 110:
		return "Proxy notification";
	case 120:
		return "Authentication notification";
	case 130:
		return "Logoff notification";
	case 140:
		return "Response to Authentication Poll";
	case 150:
		return "Response to Abort Login";
	}

	return NULL;
}

static const char *response_code_to_string(int response_code)
{
	switch (response_code) {
	case 0:
		return "No error";
	case 50:
		return "Login succeeded";
	case 100:
		return "Login failed";
	case 102:
		return "RADIUS server error/timeout";
	case 105:
		return "RADIUS server not enabled";
	case 150:
		return "Logoff succeeded";
	case 151:
		return "Login aborted";
	case 200:
		return "Proxy detection/repeat operation";
	case 201:
		return "Authentication pending";
	case 255:
		return "Access gateway internal error";
	}

	return NULL;
}

static struct {
	const char *str;
	enum {
		WISPR_ELEMENT_NONE              = 0,
		WISPR_ELEMENT_ACCESS_PROCEDURE  = 1,
		WISPR_ELEMENT_ACCESS_LOCATION   = 2,
		WISPR_ELEMENT_LOCATION_NAME     = 3,
		WISPR_ELEMENT_LOGIN_URL         = 4,
		WISPR_ELEMENT_ABORT_LOGIN_URL   = 5,
		WISPR_ELEMENT_MESSAGE_TYPE      = 6,
		WISPR_ELEMENT_RESPONSE_CODE     = 7,
		WISPR_ELEMENT_NEXT_URL          = 8,
		WISPR_ELEMENT_DELAY             = 9,
		WISPR_ELEMENT_REPLY_MESSAGE     = 10,
		WISPR_ELEMENT_LOGIN_RESULTS_URL = 11,
		WISPR_ELEMENT_LOGOFF_URL        = 12,
	} element;
} wispr_element_map[] = {
	{ "AccessProcedure",	WISPR_ELEMENT_ACCESS_PROCEDURE	},
	{ "AccessLocation",	WISPR_ELEMENT_ACCESS_LOCATION	},
	{ "LocationName",	WISPR_ELEMENT_LOCATION_NAME	},
	{ "LoginURL",		WISPR_ELEMENT_LOGIN_URL		},
	{ "AbortLoginURL",	WISPR_ELEMENT_ABORT_LOGIN_URL	},
	{ "MessageType",	WISPR_ELEMENT_MESSAGE_TYPE	},
	{ "ResponseCode",	WISPR_ELEMENT_RESPONSE_CODE	},
	{ "NextURL",		WISPR_ELEMENT_NEXT_URL		},
	{ "Delay",		WISPR_ELEMENT_DELAY		},
	{ "ReplyMessage",	WISPR_ELEMENT_REPLY_MESSAGE	},
	{ "LoginResultsURL",	WISPR_ELEMENT_LOGIN_RESULTS_URL	},
	{ "LogoffURL",		WISPR_ELEMENT_LOGOFF_URL	},
	{ NULL,			WISPR_ELEMENT_NONE		},
};

static void xml_wispr_start_element_handler(GMarkupParseContext *context,
					const gchar *element_name,
					const gchar **attribute_names,
					const gchar **attribute_values,
					gpointer user_data, GError **error)
{
	struct connman_wispr_message *msg = user_data;

	msg->current_element = element_name;
}

static void xml_wispr_end_element_handler(GMarkupParseContext *context,
					const gchar *element_name,
					gpointer user_data, GError **error)
{
	struct connman_wispr_message *msg = user_data;

	msg->current_element = NULL;
}

static void xml_wispr_text_handler(GMarkupParseContext *context,
					const gchar *text, gsize text_len,
					gpointer user_data, GError **error)
{
	struct connman_wispr_message *msg = user_data;
	int i;

	if (!msg->current_element)
		return;

	for (i = 0; wispr_element_map[i].str; i++) {
		if (!g_str_equal(wispr_element_map[i].str, msg->current_element))
			continue;

		switch (wispr_element_map[i].element) {
		case WISPR_ELEMENT_NONE:
		case WISPR_ELEMENT_ACCESS_PROCEDURE:
			g_free(msg->access_procedure);
			msg->access_procedure = g_strdup(text);
			break;
		case WISPR_ELEMENT_ACCESS_LOCATION:
			g_free(msg->access_location);
			msg->access_location = g_strdup(text);
			break;
		case WISPR_ELEMENT_LOCATION_NAME:
			g_free(msg->location_name);
			msg->location_name = g_strdup(text);
			break;
		case WISPR_ELEMENT_LOGIN_URL:
			g_free(msg->login_url);
			msg->login_url = g_strdup(text);
			break;
		case WISPR_ELEMENT_ABORT_LOGIN_URL:
			g_free(msg->abort_login_url);
			msg->abort_login_url = g_strdup(text);
			break;
		case WISPR_ELEMENT_MESSAGE_TYPE:
			msg->message_type = atoi(text);
			break;
		case WISPR_ELEMENT_RESPONSE_CODE:
			msg->response_code = atoi(text);
			break;
		case WISPR_ELEMENT_NEXT_URL:
		case WISPR_ELEMENT_DELAY:
		case WISPR_ELEMENT_REPLY_MESSAGE:
		case WISPR_ELEMENT_LOGIN_RESULTS_URL:
			break;
		case WISPR_ELEMENT_LOGOFF_URL:
			g_free(msg->logoff_url);
			msg->logoff_url = g_strdup(text);
			break;
		}
	}
}

static void xml_wispr_error_handler(GMarkupParseContext *context,
					GError *error, gpointer user_data)
{
	struct connman_wispr_message *msg = user_data;

	msg->has_error = true;
}

static const GMarkupParser xml_wispr_parser_handlers = {
	xml_wispr_start_element_handler,
	xml_wispr_end_element_handler,
	xml_wispr_text_handler,
	NULL,
	xml_wispr_error_handler,
};

static void xml_wispr_parser_callback(const char *str, gpointer user_data)
{
	struct connman_wispr_portal_context *wp_context = user_data;
	GMarkupParseContext *parser_context = NULL;
	bool result;

	DBG("");

	parser_context = g_markup_parse_context_new(&xml_wispr_parser_handlers,
					G_MARKUP_TREAT_CDATA_AS_TEXT,
					&(wp_context->wispr_msg), NULL);

	result = g_markup_parse_context_parse(parser_context,
					str, strlen(str), NULL);
	if (result)
		g_markup_parse_context_end_parse(parser_context, NULL);

	g_markup_parse_context_free(parser_context);
}

static void web_debug(const char *str, void *data)
{
	connman_info("%s: %s\n", (const char *) data, str);
}

static void wispr_portal_error(struct connman_wispr_portal_context *wp_context)
{
	DBG("Failed to proceed wispr/portal web request");

	wp_context->wispr_result = CONNMAN_WISPR_RESULT_FAILED;
}

static void portal_manage_status(GWebResult *result,
			struct connman_wispr_portal_context *wp_context)
{
	struct connman_service *service = wp_context->service;
	enum connman_ipconfig_type type = wp_context->type;
	const char *str = NULL;

	DBG("");

	/* We currently don't do anything with this info */
	if (g_web_result_get_header(result, "X-ConnMan-Client-IP",
				&str))
		connman_info("Client-IP: %s", str);

	if (g_web_result_get_header(result, "X-ConnMan-Client-Country",
				&str))
		connman_info("Client-Country: %s", str);

	if (g_web_result_get_header(result, "X-ConnMan-Client-Region",
				&str))
		connman_info("Client-Region: %s", str);

	if (g_web_result_get_header(result, "X-ConnMan-Client-Timezone",
				&str))
		connman_info("Client-Timezone: %s", str);

	__connman_service_ipconfig_indicate_state(service,
					CONNMAN_SERVICE_STATE_ONLINE, type);

	wispr_stop(wp_context, ONLINE_CHECK_SUCCESS, true);
}

static bool wispr_route_request(const char *address, int ai_family,
		int if_index, gpointer user_data)
{
	int result = -1;
	struct connman_wispr_portal_context *wp_context = user_data;
	const char *gateway;
	struct wispr_route *route;

	gateway = __connman_ipconfig_get_gateway_from_index(if_index,
		wp_context->type);

	OC_PRINT("address %s if %d gw %s", address, if_index, gateway);

	if (!gateway)
		return false;

	route = g_try_new0(struct wispr_route, 1);
	if (route == 0) {
		OC_PRINT("could not create struct");
		return false;
	}

	switch (wp_context->type) {
	case CONNMAN_IPCONFIG_TYPE_IPV4:
		result = connman_inet_add_host_route(if_index, address,
				gateway);
		break;
	case CONNMAN_IPCONFIG_TYPE_IPV6:
		result = connman_inet_add_ipv6_host_route(if_index, address,
				gateway);
		break;
	case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
	case CONNMAN_IPCONFIG_TYPE_ALL:
		break;
	}

	if (result < 0) {
		OC_PRINT("add host route failed, result %d", result);
		g_free(route);
		return false;
	}

	route->address = g_strdup(address);
	route->if_index = if_index;
	wp_context->route_list = g_slist_prepend(wp_context->route_list, route);

	return true;
}

static void wispr_portal_request_portal(
		struct connman_wispr_portal_context *wp_context)
{
	DBG("");

	wp_context->request_id = g_web_request_get(wp_context->web,
					wp_context->status_url,
					wp_context->wispr_result_func,
					wispr_route_request,
					wp_context);

	if (wp_context->request_id == 0) {
		OC_PRINT("g_web_request_get return error");
		wispr_portal_error(wp_context);
	}
}

static bool wispr_input(const guint8 **data, gsize *length,
						gpointer user_data)
{
	struct connman_wispr_portal_context *wp_context = user_data;
	GString *buf;
	gsize count;

	DBG("");

	buf = g_string_sized_new(100);

	g_string_append(buf, "button=Login&UserName=");
	g_string_append_uri_escaped(buf, wp_context->wispr_username,
								NULL, FALSE);
	g_string_append(buf, "&Password=");
	g_string_append_uri_escaped(buf, wp_context->wispr_password,
								NULL, FALSE);
	g_string_append(buf, "&FNAME=0&OriginatingServer=");
	g_string_append_uri_escaped(buf, wp_context->status_url, NULL, FALSE);

	count = buf->len;

	g_free(wp_context->wispr_formdata);
	wp_context->wispr_formdata = g_string_free(buf, FALSE);

	*data = (guint8 *) wp_context->wispr_formdata;
	*length = count;

	return false;
}

static void wispr_portal_browser_reply_cb(struct connman_service *service,
					bool authentication_done,
					const char *error, void *user_data)
{
	struct connman_wispr_portal_context *wp_context = user_data;

	DBG("");

	if (!service || !wp_context)
		return;

	if (!authentication_done) {
		OC_PRINT("authentication not done");
		wispr_portal_error(wp_context);
		free_wispr_routes(wp_context);
		return;
	}

	/* Restarting the test */
	__connman_wispr_start(service, wp_context->type, wp_context->wispr_server);
}

static void wispr_portal_request_wispr_login(struct connman_service *service,
				bool success,
				const char *ssid, int ssid_len,
				const char *username, const char *password,
				bool wps, const char *wpspin,
				const char *error, void *user_data)
{
	struct connman_wispr_portal_context *wp_context = user_data;

	DBG("");

	if (error) {
		if (g_strcmp0(error,
			"net.connman.Agent.Error.LaunchBrowser") == 0) {
			if (__connman_agent_request_browser(service,
					wispr_portal_browser_reply_cb,
					wp_context->redirect_url,
					wp_context) == -EINPROGRESS)
				return;
		}

		wispr_stop(wp_context, ONLINE_CHECK_FAIL, true);
		return;
	}

	g_free(wp_context->wispr_username);
	wp_context->wispr_username = g_strdup(username);

	g_free(wp_context->wispr_password);
	wp_context->wispr_password = g_strdup(password);

	wp_context->request_id = g_web_request_post(wp_context->web,
					wp_context->wispr_msg.login_url,
					"application/x-www-form-urlencoded",
					wispr_input, wp_context->wispr_result_func,
					wp_context);

	connman_wispr_message_init(&wp_context->wispr_msg);
}

static bool wispr_manage_message(GWebResult *result,
			struct connman_wispr_portal_context *wp_context)
{
	DBG("Message type: %s (%d)",
		message_type_to_string(wp_context->wispr_msg.message_type),
					wp_context->wispr_msg.message_type);
	DBG("Response code: %s (%d)",
		response_code_to_string(wp_context->wispr_msg.response_code),
					wp_context->wispr_msg.response_code);

	if (wp_context->wispr_msg.access_procedure)
		DBG("Access procedure: %s",
			wp_context->wispr_msg.access_procedure);
	if (wp_context->wispr_msg.access_location)
		DBG("Access location: %s",
			wp_context->wispr_msg.access_location);
	if (wp_context->wispr_msg.location_name)
		DBG("Location name: %s",
			wp_context->wispr_msg.location_name);
	if (wp_context->wispr_msg.login_url)
		DBG("Login URL: %s", wp_context->wispr_msg.login_url);
	if (wp_context->wispr_msg.abort_login_url)
		DBG("Abort login URL: %s",
			wp_context->wispr_msg.abort_login_url);
	if (wp_context->wispr_msg.logoff_url)
		DBG("Logoff URL: %s", wp_context->wispr_msg.logoff_url);

	switch (wp_context->wispr_msg.message_type) {
	case 100:
		DBG("Login required");

		wp_context->wispr_result = CONNMAN_WISPR_RESULT_LOGIN;

		if (__connman_agent_request_login_input(wp_context->service,
					wispr_portal_request_wispr_login,
					wp_context) != -EINPROGRESS)
			wispr_portal_error(wp_context);
		else
			return true;

		break;
	case 120: /* Falling down */
	case 140:
		if (wp_context->wispr_msg.response_code == 50) {
			wp_context->wispr_result = CONNMAN_WISPR_RESULT_ONLINE;

			g_free(wp_context->wispr_username);
			wp_context->wispr_username = NULL;

			g_free(wp_context->wispr_password);
			wp_context->wispr_password = NULL;

			g_free(wp_context->wispr_formdata);
			wp_context->wispr_formdata = NULL;

			wispr_portal_request_portal(wp_context);

			return true;
		} else
			wispr_portal_error(wp_context);

		break;
	default:
		break;
	}

	return false;
}

static bool wispr_portal_web_result_connman(GWebResult *result, gpointer user_data)
{
	struct connman_wispr_portal_context *wp_context = user_data;
	const char *redirect = NULL;
	const guint8 *chunk = NULL;
	const char *str = NULL;
	guint16 status;
	gsize length;

	DBG("");

	if (wp_context->wispr_result != CONNMAN_WISPR_RESULT_ONLINE) {
		g_web_result_get_chunk(result, &chunk, &length);

		if (length > 0) {
			g_web_parser_feed_data(wp_context->wispr_parser,
								chunk, length);
			return true;
		}

		g_web_parser_end_data(wp_context->wispr_parser);

		if (wp_context->wispr_msg.message_type >= 0) {
			if (wispr_manage_message(result, wp_context))
				goto done;
		}
	}

	status = g_web_result_get_status(result);

	DBG("status: %03u", status);

	switch (status) {
	case 000:
		__connman_agent_request_browser(wp_context->service,
				wispr_portal_browser_reply_cb,
				wp_context->status_url, wp_context);
		break;
	case 200:
		if (wp_context->wispr_msg.message_type >= 0)
			break;

		if (g_web_result_get_header(result, "X-ConnMan-Status",
						&str)) {
			portal_manage_status(result, wp_context);
			return false;
		} else
			__connman_agent_request_browser(wp_context->service,
					wispr_portal_browser_reply_cb,
					wp_context->redirect_url, wp_context);

		break;
	case 302:
		if (!g_web_supports_tls() ||
			!g_web_result_get_header(result, "Location",
							&redirect)) {

			__connman_agent_request_browser(wp_context->service,
					wispr_portal_browser_reply_cb,
					wp_context->status_url, wp_context);
			break;
		}

		DBG("Redirect URL: %s", redirect);

		wp_context->redirect_url = g_strdup(redirect);

		wp_context->request_id = g_web_request_get(wp_context->web,
				redirect, wispr_portal_web_result_connman,
				wispr_route_request, wp_context);

		goto done;
	case 400:
	case 404:
	case 9002:
		if (__connman_service_online_check_failed(wp_context->service,
						wp_context->type) == 0) {
			wispr_portal_error(wp_context);
			wispr_stop(wp_context, (status == 9002) ? ONLINE_CHECK_DNS_FAIL : ONLINE_CHECK_FAIL, true);
			return false;
		}

		break;
	case 505:
		__connman_agent_request_browser(wp_context->service,
				wispr_portal_browser_reply_cb,
				wp_context->status_url, wp_context);
		break;
	default:
		break;
	}

	free_wispr_routes(wp_context);
	wp_context->request_id = 0;
done:
	wp_context->wispr_msg.message_type = -1;
	return false;
}

static bool wispr_portal_web_result_google(GWebResult *result, gpointer user_data)
{
	struct connman_wispr_portal_context *wp_context = user_data;
	const guint8 *chunk = NULL;
	guint16 status;
	gsize length;

	DBG("");

	if (wp_context->wispr_result != CONNMAN_WISPR_RESULT_ONLINE) {
		g_web_result_get_chunk(result, &chunk, &length);

		if (length > 0) {
			g_web_parser_feed_data(wp_context->wispr_parser,
								chunk, length);
			return true;
		}

		g_web_parser_end_data(wp_context->wispr_parser);

		if (wp_context->wispr_msg.message_type >= 0) {
			if (wispr_manage_message(result, wp_context))
				goto done;
		}
	}

	status = g_web_result_get_status(result);

	OC_PRINT("status: %03u", status);

	switch (status) {
	case 000:
		__connman_agent_request_browser(wp_context->service,
				wispr_portal_browser_reply_cb,
				wp_context->status_url, wp_context);
		break;

	case 200: // It means: "OK"
	case 204: // It means: "No content"
	case 206: // It means: "Partial content"
	case 301: // It means: "Moved permanently"
	case 302: // It means: "Found"

		if (wp_context->wispr_msg.message_type >= 0)
			break;

		portal_manage_status(result, wp_context);
		return false;

	case 400:
	case 404:
	case 9002:
		if (__connman_service_online_check_failed(wp_context->service,
						wp_context->type) == 0) {
			wispr_portal_error(wp_context);
			wispr_stop(wp_context, (status == 9002) ? ONLINE_CHECK_DNS_FAIL : ONLINE_CHECK_FAIL, true);
			return false;
		}

		break;
	case 505:
		__connman_agent_request_browser(wp_context->service,
				wispr_portal_browser_reply_cb,
				wp_context->status_url, wp_context);
		break;
	default:
		break;
	}

	free_wispr_routes(wp_context);
	wp_context->request_id = 0;
done:
	wp_context->wispr_msg.message_type = -1;
	return false;
}


static void proxy_callback(const char *proxy, void *user_data)
{
	struct connman_wispr_portal_context *wp_context = user_data;

	DBG("proxy %s", proxy);

	if (!wp_context)
		return;

	wp_context->token = 0;

	if (proxy && g_strcmp0(proxy, "DIRECT") != 0) {
		if (g_str_has_prefix(proxy, "PROXY")) {
			proxy += 5;
			for (; *proxy == ' ' && *proxy != '\0'; proxy++);
		}
		g_web_set_proxy(wp_context->web, proxy);
	}

	g_web_set_accept(wp_context->web, NULL);
	g_web_set_user_agent(wp_context->web, "ConnMan/%s wispr", VERSION);
	g_web_set_close_connection(wp_context->web, TRUE);

	connman_wispr_message_init(&wp_context->wispr_msg);

	wp_context->wispr_parser = g_web_parser_new(
					"<WISPAccessGatewayParam",
					"WISPAccessGatewayParam>",
					xml_wispr_parser_callback, wp_context);

	wispr_portal_request_portal(wp_context);
}

static gboolean no_proxy_callback(gpointer user_data)
{
	struct connman_wispr_portal_context *wp_context = user_data;

	wp_context->timeout = 0;

	proxy_callback("DIRECT", wp_context);

	return FALSE;
}

static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
{
	enum connman_service_proxy_method proxy_method;
	enum connman_service_type service_type;
	char *interface = NULL;
	char **nameservers = NULL;
	int if_index;
	int err = 0;
	int i;

	DBG("wispr/portal context %p", wp_context);
	DBG("service %p", wp_context->service);

	service_type = connman_service_get_type(wp_context->service);

	switch (service_type) {
	case CONNMAN_SERVICE_TYPE_ETHERNET:
	case CONNMAN_SERVICE_TYPE_WIFI:
	case CONNMAN_SERVICE_TYPE_BLUETOOTH:
	case CONNMAN_SERVICE_TYPE_CELLULAR:
	case CONNMAN_SERVICE_TYPE_GADGET:
		break;
	case CONNMAN_SERVICE_TYPE_UNKNOWN:
	case CONNMAN_SERVICE_TYPE_SYSTEM:
	case CONNMAN_SERVICE_TYPE_GPS:
	case CONNMAN_SERVICE_TYPE_VPN:
	case CONNMAN_SERVICE_TYPE_P2P:
	case CONNMAN_SERVICE_TYPE_LOWPAN:
		return -EOPNOTSUPP;
	}

	interface = connman_service_get_interface(wp_context->service);
	if (!interface) {
		OC_PRINT("can't find interface for wp_context %p", wp_context);
		return -EINVAL;
	}

	DBG("interface %s", interface);

	if_index = connman_inet_ifindex(interface);
	if (if_index < 0) {
		OC_PRINT("Could not get ifindex");
		err = -EINVAL;
		goto done;
	}

	nameservers = connman_service_get_nameservers(wp_context->service);
	if (!nameservers) {
		OC_PRINT("Could not get nameservers");
		err = -EINVAL;
		goto done;
	}

	wp_context->web = g_web_new(if_index);
	if (!wp_context->web) {
		OC_PRINT("Could not set up GWeb");
		err = -ENOMEM;
		goto done;
	}

	//if (getenv("CONNMAN_WEB_DEBUG"))
		g_web_set_debug(wp_context->web, web_debug, OC_TAG);

	if (wp_context->wispr_server == CONNMAN_WISPR_SERVER_CONNMAN) {
		if (wp_context->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
			g_web_set_address_family(wp_context->web, AF_INET);
			wp_context->status_url = STATUS_URL_IPV4;
		} else {
			g_web_set_address_family(wp_context->web, AF_INET6);
			wp_context->status_url = STATUS_URL_IPV6;
		}
		wp_context->wispr_result_func = wispr_portal_web_result_connman;
	} else {
		if (wp_context->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
			g_web_set_address_family(wp_context->web, AF_INET);
			wp_context->status_url = STATUS_URL_GOOGLE;
		} else {
			g_web_set_address_family(wp_context->web, AF_INET6);
			wp_context->status_url = STATUS_URL_GOOGLE;
		}
		wp_context->wispr_result_func = wispr_portal_web_result_google;
	}

	for (i = 0; nameservers[i]; i++)
		g_web_add_nameserver(wp_context->web, nameservers[i]);

	proxy_method = connman_service_get_proxy_method(wp_context->service);

	if (proxy_method != CONNMAN_SERVICE_PROXY_METHOD_DIRECT) {
		wp_context->token = connman_proxy_lookup(interface,
						wp_context->status_url,
						wp_context->service,
						proxy_callback, wp_context);

		if (wp_context->token == 0) {
			err = -EINVAL;
			OC_PRINT("connman_proxy_lookup failed");
			wispr_stop(wp_context, ONLINE_CHECK_FAIL, true);
		}
	} else if (wp_context->timeout == 0) {
		wp_context->timeout =
			g_timeout_add_seconds(0, no_proxy_callback, wp_context);
	}

done:
	g_strfreev(nameservers);

	g_free(interface);
	return err;
}

int __connman_wispr_start(struct connman_service *service,
					enum connman_ipconfig_type type, enum connman_wispr_server wispr_server)
{
	struct connman_wispr_portal_context *wp_context = NULL;
	struct connman_wispr_portal *wispr_portal = NULL;
	int index;

	DBG("service %p", service);

	if (!wispr_portal_list)
		return -EINVAL;

	index = __connman_service_get_index(service);
	if (index < 0) {
		OC_PRINT("can't find index for service %p", service);
		return -EINVAL;
	}

	wispr_portal = g_hash_table_lookup(wispr_portal_list,
					GINT_TO_POINTER(index));
	if (!wispr_portal) {
		wispr_portal = g_try_new0(struct connman_wispr_portal, 1);
		if (!wispr_portal) {
			OC_PRINT("failed to allocate portal structure");
			return -ENOMEM;
		}

		g_hash_table_replace(wispr_portal_list,
					GINT_TO_POINTER(index), wispr_portal);
	}

	if ((type != CONNMAN_IPCONFIG_TYPE_IPV4) && (type != CONNMAN_IPCONFIG_TYPE_IPV6)) {
		OC_PRINT("check type %d is not valid", type);
		return -EINVAL;
	}

	wp_context = create_wispr_portal_context();
	if (!wp_context) {
		OC_PRINT("failed to create portal context");
		return -ENOMEM;
	}

	wp_context->service = service;
	wp_context->type = type;
	wp_context->wispr_portal = wispr_portal;
	wp_context->wispr_server = wispr_server;

	wispr_start(wp_context, true);

	if (wispr_pending_timeout)
		g_source_remove(wispr_pending_timeout);
	wispr_pending_timeout = g_timeout_add_seconds(0, wispr_schedule_pendings, NULL);

	return 0;
}

void __connman_wispr_stop(struct connman_service *service)
{
	int index;
	struct connman_wispr_portal *wispr_portal = NULL;
	struct connman_wispr_portal_context *wp_context = NULL;

	DBG("service %p", service);

	if (!wispr_portal_list)
		return;

	index = __connman_service_get_index(service);
	if (index < 0) {
		OC_PRINT("can't find index for service %p", service);
		return;
	}

	wispr_portal = g_hash_table_lookup(wispr_portal_list,
						GINT_TO_POINTER(index));

	if (!wispr_portal)
		return;

	if (wispr_portal->ipv4_context)
		wp_context = wispr_portal->ipv4_context;
	else if (wispr_portal->ipv6_context)
		wp_context = wispr_portal->ipv6_context;

	if (!wp_context)
		return;

	if (wp_context->service == service) {
		wispr_cleanup_pendings(wp_context->service);
		g_hash_table_remove(wispr_portal_list, GINT_TO_POINTER(index));
	} else {
		DBG("service not match, dont stop wispr");
	}
}

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

	wispr_portal_list = g_hash_table_new_full(g_direct_hash,
						g_direct_equal, NULL,
						free_connman_wispr_portal);

	return 0;
}

void __connman_wispr_cleanup(void)
{
	DBG("");

	/* flush pending list */
	if (wispr_pending)
		wispr_cleanup_pendings(NULL);

	g_hash_table_destroy(wispr_portal_list);
	wispr_portal_list = NULL;
}
