/*
 *
 *  oFono - Open Source Telephony
 *
 *  Copyright (C) 2008-2011  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 <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>

#include <glib.h>

#define OFONO_API_SUBJECT_TO_CHANGE
#include <ofono/modem.h>
#include <ofono/gprs-provision.h>

#ifndef MBPI_DATABASE
#define MBPI_DATABASE  "/usr/share/mobile-broadband-provider-info/" \
							"serviceproviders.xml"
#endif

#include "mbpi.h"

#define _(x) case x: return (#x)

enum MBPI_ERROR {
	MBPI_ERROR_DUPLICATE,
};

struct gsm_data {
	const char *match_mcc;
	const char *match_mnc;
	GSList *apns;
	gboolean match_found;
	gboolean allow_duplicates;
};

struct cdma_data {
	const char *match_sid;
	char *provider_name;
	gboolean match_found;
};

const char *mbpi_ap_type(enum ofono_gprs_context_type type)
{
	switch (type) {
		_(OFONO_GPRS_CONTEXT_TYPE_ANY);
		_(OFONO_GPRS_CONTEXT_TYPE_INTERNET);
		_(OFONO_GPRS_CONTEXT_TYPE_MMS);
		_(OFONO_GPRS_CONTEXT_TYPE_WAP);
		_(OFONO_GPRS_CONTEXT_TYPE_IMS);
	}

	return "OFONO_GPRS_CONTEXT_TYPE_<UNKNOWN>";
}

static GQuark mbpi_error_quark(void)
{
	return g_quark_from_static_string("ofono-mbpi-error-quark");
}

void mbpi_ap_free(struct ofono_gprs_provision_data *ap)
{
	g_free(ap->name);
	g_free(ap->apn);
	g_free(ap->username);
	g_free(ap->password);
	g_free(ap->message_proxy);
	g_free(ap->message_center);

	g_free(ap);
}

static void mbpi_g_set_error(GMarkupParseContext *context, GError **error,
				GQuark domain, gint code, const gchar *fmt, ...)
{
	va_list ap;
	gint line_number, char_number;

	g_markup_parse_context_get_position(context, &line_number,
						&char_number);
	va_start(ap, fmt);

	*error = g_error_new_valist(domain, code, fmt, ap);

	va_end(ap);

	g_prefix_error(error, "%s:%d ", MBPI_DATABASE, line_number);
}

static void text_handler(GMarkupParseContext *context,
				const gchar *text, gsize text_len,
				gpointer userdata, GError **error)
{
	char **string = userdata;

	*string = g_strndup(text, text_len);
}

static const GMarkupParser text_parser = {
	NULL,
	NULL,
	text_handler,
	NULL,
	NULL,
};

static void authentication_start(GMarkupParseContext *context,
			const gchar **attribute_names,
			const gchar **attribute_values,
			enum ofono_gprs_auth_method *auth_method,
			GError **error)
{
	const char *text = NULL;
	int i;

	for (i = 0; attribute_names[i]; i++)
		if (g_str_equal(attribute_names[i], "method") == TRUE)
			text = attribute_values[i];

	if (text == NULL) {
		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
					"Missing attribute: method");
		return;
	}

	if (strcmp(text, "chap") == 0)
		*auth_method = OFONO_GPRS_AUTH_METHOD_CHAP;
	else if (strcmp(text, "pap") == 0)
		*auth_method = OFONO_GPRS_AUTH_METHOD_PAP;
	else
		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
					G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
					"Unknown authentication method: %s",
					text);
}

static void usage_start(GMarkupParseContext *context,
			const gchar **attribute_names,
			const gchar **attribute_values,
			enum ofono_gprs_context_type *type, GError **error)
{
	const char *text = NULL;
	int i;

	for (i = 0; attribute_names[i]; i++)
		if (g_str_equal(attribute_names[i], "type") == TRUE)
			text = attribute_values[i];

	if (text == NULL) {
		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
					"Missing attribute: type");
		return;
	}

	if (strcmp(text, "internet") == 0)
		*type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
	else if (strcmp(text, "mms") == 0)
		*type = OFONO_GPRS_CONTEXT_TYPE_MMS;
	else if (strcmp(text, "wap") == 0)
		*type = OFONO_GPRS_CONTEXT_TYPE_WAP;
	else
		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
					G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
					"Unknown usage attribute: %s", text);
}

static void apn_start(GMarkupParseContext *context, const gchar *element_name,
			const gchar **attribute_names,
			const gchar **attribute_values,
			gpointer userdata, GError **error)
{
	struct ofono_gprs_provision_data *apn = userdata;

	if (g_str_equal(element_name, "name"))
		g_markup_parse_context_push(context, &text_parser, &apn->name);
	else if (g_str_equal(element_name, "username"))
		g_markup_parse_context_push(context, &text_parser,
						&apn->username);
	else if (g_str_equal(element_name, "password"))
		g_markup_parse_context_push(context, &text_parser,
						&apn->password);
	else if (g_str_equal(element_name, "authentication"))
		authentication_start(context, attribute_names,
				attribute_values, &apn->auth_method, error);
	else if (g_str_equal(element_name, "mmsc"))
		g_markup_parse_context_push(context, &text_parser,
						&apn->message_center);
	else if (g_str_equal(element_name, "mmsproxy"))
		g_markup_parse_context_push(context, &text_parser,
						&apn->message_proxy);
	else if (g_str_equal(element_name, "usage"))
		usage_start(context, attribute_names, attribute_values,
				&apn->type, error);
}

static void apn_end(GMarkupParseContext *context, const gchar *element_name,
			gpointer userdata, GError **error)
{
	if (g_str_equal(element_name, "name") ||
			g_str_equal(element_name, "username") ||
			g_str_equal(element_name, "password") ||
			g_str_equal(element_name, "mmsc") ||
			g_str_equal(element_name, "mmsproxy"))
		g_markup_parse_context_pop(context);
}

static void apn_error(GMarkupParseContext *context, GError *error,
			gpointer userdata)
{
	/*
	 * Note that even if the error happened in a subparser, this will
	 * be called.  So we always perform cleanup of the allocated
	 * provision data
	 */
	mbpi_ap_free(userdata);
}

static const GMarkupParser apn_parser = {
	apn_start,
	apn_end,
	NULL,
	NULL,
	apn_error,
};

static const GMarkupParser skip_parser = {
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
};

static void network_id_handler(GMarkupParseContext *context,
				struct gsm_data *gsm,
				const gchar **attribute_names,
				const gchar **attribute_values,
				GError **error)
{
	const char *mcc = NULL, *mnc = NULL;
	int i;

	for (i = 0; attribute_names[i]; i++) {
		if (g_str_equal(attribute_names[i], "mcc") == TRUE)
			mcc = attribute_values[i];
		if (g_str_equal(attribute_names[i], "mnc") == TRUE)
			mnc = attribute_values[i];
	}

	if (mcc == NULL) {
		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
					"Missing attribute: mcc");
		return;
	}

	if (mnc == NULL) {
		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
					"Missing attribute: mnc");
		return;
	}

	if (g_str_equal(mcc, gsm->match_mcc) &&
			g_str_equal(mnc, gsm->match_mnc))
		gsm->match_found = TRUE;
}

static void apn_handler(GMarkupParseContext *context, struct gsm_data *gsm,
			const gchar **attribute_names,
			const gchar **attribute_values,
			GError **error)
{
	struct ofono_gprs_provision_data *ap;
	const char *apn;
	int i;

	if (gsm->match_found == FALSE) {
		g_markup_parse_context_push(context, &skip_parser, NULL);
		return;
	}

	for (i = 0, apn = NULL; attribute_names[i]; i++) {
		if (g_str_equal(attribute_names[i], "value") == FALSE)
			continue;

		apn = attribute_values[i];
		break;
	}

	if (apn == NULL) {
		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
					"APN attribute missing");
		return;
	}

	ap = g_new0(struct ofono_gprs_provision_data, 1);
	ap->apn = g_strdup(apn);
	ap->type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
	ap->proto = OFONO_GPRS_PROTO_IP;

	/* pre-select default authentication method */
	ap->auth_method = OFONO_GPRS_AUTH_METHOD_CHAP;

	g_markup_parse_context_push(context, &apn_parser, ap);
}

static void sid_handler(GMarkupParseContext *context,
				struct cdma_data *cdma,
				const gchar **attribute_names,
				const gchar **attribute_values,
				GError **error)
{
	const char *sid = NULL;
	int i;

	for (i = 0; attribute_names[i]; i++) {
		if (g_str_equal(attribute_names[i], "value") == FALSE)
			continue;

		sid = attribute_values[i];
		break;
	}

	if (sid == NULL) {
		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
					"Missing attribute: sid");
		return;
	}

	if (g_str_equal(sid, cdma->match_sid))
		cdma->match_found = TRUE;
}

static void gsm_start(GMarkupParseContext *context, const gchar *element_name,
			const gchar **attribute_names,
			const gchar **attribute_values,
			gpointer userdata, GError **error)
{
	if (g_str_equal(element_name, "network-id")) {
		struct gsm_data *gsm = userdata;

		/*
		 * For entries with multiple network-id elements, don't bother
		 * searching if we already have a match
		 */
		if (gsm->match_found == TRUE)
			return;

		network_id_handler(context, userdata, attribute_names,
					attribute_values, error);
	} else if (g_str_equal(element_name, "apn"))
		apn_handler(context, userdata, attribute_names,
				attribute_values, error);
}

static void gsm_end(GMarkupParseContext *context, const gchar *element_name,
			gpointer userdata, GError **error)
{
	struct gsm_data *gsm;
	struct ofono_gprs_provision_data *ap;

	if (!g_str_equal(element_name, "apn"))
		return;

	gsm = userdata;

	ap = g_markup_parse_context_pop(context);
	if (ap == NULL)
		return;

	/* select authentication method NONE if fit */
	if (!ap->username || !ap->password)
		ap->auth_method = OFONO_GPRS_AUTH_METHOD_NONE;

	if (gsm->allow_duplicates == FALSE) {
		GSList *l;

		for (l = gsm->apns; l; l = l->next) {
			struct ofono_gprs_provision_data *pd = l->data;

			if (pd->type != ap->type)
				continue;

			mbpi_g_set_error(context, error, mbpi_error_quark(),
						MBPI_ERROR_DUPLICATE,
						"Duplicate context detected");

			mbpi_ap_free(ap);
			return;
		}
	}

	gsm->apns = g_slist_append(gsm->apns, ap);
}

static const GMarkupParser gsm_parser = {
	gsm_start,
	gsm_end,
	NULL,
	NULL,
	NULL,
};

static void cdma_start(GMarkupParseContext *context, const gchar *element_name,
			const gchar **attribute_names,
			const gchar **attribute_values,
			gpointer userdata, GError **error)
{
	if (g_str_equal(element_name, "sid")) {
		struct cdma_data *cdma = userdata;
		/*
		 * For entries with multiple sid elements, don't bother
		 * searching if we already have a match
		 */
		if (cdma->match_found == TRUE)
			return;

		sid_handler(context, cdma, attribute_names, attribute_values,
				error);
	}
}

static const GMarkupParser cdma_parser = {
	cdma_start,
	NULL,
	NULL,
	NULL,
	NULL,
};

static void provider_start(GMarkupParseContext *context,
				const gchar *element_name,
				const gchar **attribute_names,
				const gchar **attribute_values,
				gpointer userdata, GError **error)
{
	if (g_str_equal(element_name, "name")) {
		struct cdma_data *cdma = userdata;

		g_free(cdma->provider_name);
		cdma->provider_name = NULL;
		g_markup_parse_context_push(context, &text_parser,
						&cdma->provider_name);
	} else if (g_str_equal(element_name, "gsm"))
		g_markup_parse_context_push(context, &skip_parser, NULL);
	else if (g_str_equal(element_name, "cdma"))
		g_markup_parse_context_push(context, &cdma_parser, userdata);
}

static void provider_end(GMarkupParseContext *context,
					const gchar *element_name,
					gpointer userdata, GError **error)
{
	if (g_str_equal(element_name, "name") ||
				g_str_equal(element_name, "gsm") ||
				g_str_equal(element_name, "cdma"))
		g_markup_parse_context_pop(context);

}

static const GMarkupParser provider_parser = {
	provider_start,
	provider_end,
	NULL,
	NULL,
	NULL,
};

static void toplevel_gsm_start(GMarkupParseContext *context,
					const gchar *element_name,
					const gchar **atribute_names,
					const gchar **attribute_values,
					gpointer userdata, GError **error)
{
	struct gsm_data *gsm = userdata;

	if (g_str_equal(element_name, "gsm")) {
		gsm->match_found = FALSE;
		g_markup_parse_context_push(context, &gsm_parser, gsm);
	} else if (g_str_equal(element_name, "cdma"))
		g_markup_parse_context_push(context, &skip_parser, NULL);
}

static void toplevel_gsm_end(GMarkupParseContext *context,
					const gchar *element_name,
					gpointer userdata, GError **error)
{
	if (g_str_equal(element_name, "gsm") ||
			g_str_equal(element_name, "cdma"))
		g_markup_parse_context_pop(context);
}

static const GMarkupParser toplevel_gsm_parser = {
	toplevel_gsm_start,
	toplevel_gsm_end,
	NULL,
	NULL,
	NULL,
};

static void toplevel_cdma_start(GMarkupParseContext *context,
					const gchar *element_name,
					const gchar **atribute_names,
					const gchar **attribute_values,
					gpointer userdata, GError **error)
{
	struct cdma_data *cdma = userdata;

	if (g_str_equal(element_name, "provider") == FALSE)
		return;

	if (cdma->match_found == TRUE)
		g_markup_parse_context_push(context, &skip_parser, NULL);
	else
		g_markup_parse_context_push(context, &provider_parser, cdma);
}

static void toplevel_cdma_end(GMarkupParseContext *context,
					const gchar *element_name,
					gpointer userdata, GError **error)
{
	if (g_str_equal(element_name, "provider"))
		g_markup_parse_context_pop(context);
}

static const GMarkupParser toplevel_cdma_parser = {
	toplevel_cdma_start,
	toplevel_cdma_end,
	NULL,
	NULL,
	NULL,
};

static gboolean mbpi_parse(const GMarkupParser *parser, gpointer userdata,
				GError **error)
{
	struct stat st;
	char *db;
	int fd;
	GMarkupParseContext *context;
	gboolean ret;

	fd = open(MBPI_DATABASE, O_RDONLY);
	if (fd < 0) {
		g_set_error(error, G_FILE_ERROR,
				g_file_error_from_errno(errno),
				"open(%s) failed: %s", MBPI_DATABASE,
				g_strerror(errno));
		return FALSE;
	}

	if (fstat(fd, &st) < 0) {
		close(fd);
		g_set_error(error, G_FILE_ERROR,
				g_file_error_from_errno(errno),
				"fstat(%s) failed: %s", MBPI_DATABASE,
				g_strerror(errno));
		return FALSE;
	}

	db = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
	if (db == MAP_FAILED) {
		close(fd);
		g_set_error(error, G_FILE_ERROR,
				g_file_error_from_errno(errno),
				"mmap(%s) failed: %s", MBPI_DATABASE,
				g_strerror(errno));
		return FALSE;
	}

	context = g_markup_parse_context_new(parser,
						G_MARKUP_TREAT_CDATA_AS_TEXT,
						userdata, NULL);

	ret = g_markup_parse_context_parse(context, db, st.st_size, error);

	if (ret == TRUE)
		g_markup_parse_context_end_parse(context, error);

	munmap(db, st.st_size);
	close(fd);
	g_markup_parse_context_free(context);

	return ret;
}

GSList *mbpi_lookup_apn(const char *mcc, const char *mnc,
			gboolean allow_duplicates, GError **error)
{
	struct gsm_data gsm;
	GSList *l;

	memset(&gsm, 0, sizeof(gsm));
	gsm.match_mcc = mcc;
	gsm.match_mnc = mnc;
	gsm.allow_duplicates = allow_duplicates;

	if (mbpi_parse(&toplevel_gsm_parser, &gsm, error) == FALSE) {
		for (l = gsm.apns; l; l = l->next)
			mbpi_ap_free(l->data);

		g_slist_free(gsm.apns);
		gsm.apns = NULL;
	}

	return gsm.apns;
}

char *mbpi_lookup_cdma_provider_name(const char *sid, GError **error)
{
	struct cdma_data cdma;

	memset(&cdma, 0, sizeof(cdma));
	cdma.match_sid = sid;

	if (mbpi_parse(&toplevel_cdma_parser, &cdma, error) == FALSE) {
		g_free(cdma.provider_name);
		cdma.provider_name = NULL;
	}

	return cdma.provider_name;
}
