/*
 * Hotspot 2.0 SPP server - standalone version
 * Copyright (c) 2012-2013, Qualcomm Atheros, Inc.
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"
#include <time.h>
#include <sqlite3.h>

#include "common.h"
#include "xml-utils.h"
#include "spp_server.h"


static void write_timestamp(FILE *f)
{
	time_t t;
	struct tm *tm;

	time(&t);
	tm = localtime(&t);

	fprintf(f, "%04u-%02u-%02u %02u:%02u:%02u ",
		tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
		tm->tm_hour, tm->tm_min, tm->tm_sec);
}


void debug_print(struct hs20_svc *ctx, int print, const char *fmt, ...)
{
	va_list ap;

	if (ctx->debug_log == NULL)
		return;

	write_timestamp(ctx->debug_log);
	va_start(ap, fmt);
	vfprintf(ctx->debug_log, fmt, ap);
	va_end(ap);

	fprintf(ctx->debug_log, "\n");
}


void debug_dump_node(struct hs20_svc *ctx, const char *title, xml_node_t *node)
{
	char *str;

	if (ctx->debug_log == NULL)
		return;
	str = xml_node_to_str(ctx->xml, node);
	if (str == NULL)
		return;

	write_timestamp(ctx->debug_log);
	fprintf(ctx->debug_log, "%s: '%s'\n", title, str);
	os_free(str);
}


static int process(struct hs20_svc *ctx)
{
	int dmacc = 0;
	xml_node_t *soap, *spp, *resp;
	char *user, *realm, *post, *str;

	ctx->addr = getenv("HS20ADDR");
	if (ctx->addr)
		debug_print(ctx, 1, "Connection from %s", ctx->addr);

	user = getenv("HS20USER");
	if (user && strlen(user) == 0)
		user = NULL;
	realm = getenv("HS20REALM");
	if (realm == NULL) {
		debug_print(ctx, 1, "HS20REALM not set");
		return -1;
	}
	post = getenv("HS20POST");
	if (post == NULL) {
		debug_print(ctx, 1, "HS20POST not set");
		return -1;
	}

	soap = xml_node_from_buf(ctx->xml, post);
	if (soap == NULL) {
		debug_print(ctx, 1, "Could not parse SOAP data");
		return -1;
	}
	debug_dump_node(ctx, "Received SOAP message", soap);
	spp = soap_get_body(ctx->xml, soap);
	if (spp == NULL) {
		debug_print(ctx, 1, "Could not get SPP message");
		xml_node_free(ctx->xml, soap);
		return -1;
	}
	debug_dump_node(ctx, "Received SPP message", spp);

	resp = hs20_spp_server_process(ctx, spp, user, realm, dmacc);
	xml_node_free(ctx->xml, soap);
	if (resp == NULL && user == NULL) {
		debug_print(ctx, 1, "Request HTTP authentication");
		return 2; /* Request authentication */
	}
	if (resp == NULL) {
		debug_print(ctx, 1, "No response");
		return -1;
	}

	soap = soap_build_envelope(ctx->xml, resp);
	if (soap == NULL) {
		debug_print(ctx, 1, "SOAP envelope building failed");
		return -1;
	}
	str = xml_node_to_str(ctx->xml, soap);
	xml_node_free(ctx->xml, soap);
	if (str == NULL) {
		debug_print(ctx, 1, "Could not get node string");
		return -1;
	}
	printf("%s", str);
	free(str);

	return 0;
}


static void usage(void)
{
	printf("usage:\n"
	       "hs20_spp_server -r<root directory> [-f<debug log>]\n");
}


int main(int argc, char *argv[])
{
	struct hs20_svc ctx;
	int ret;

	os_memset(&ctx, 0, sizeof(ctx));
	for (;;) {
		int c = getopt(argc, argv, "f:r:");
		if (c < 0)
			break;
		switch (c) {
		case 'f':
			if (ctx.debug_log)
				break;
			ctx.debug_log = fopen(optarg, "a");
			if (ctx.debug_log == NULL) {
				printf("Could not write to %s\n", optarg);
				return -1;
			}
			break;
		case 'r':
			ctx.root_dir = optarg;
			break;
		default:
			usage();
			return -1;
		}
	}
	if (ctx.root_dir == NULL) {
		usage();
		return -1;
	}
	ctx.xml = xml_node_init_ctx(&ctx, NULL);
	if (ctx.xml == NULL)
		return -1;
	if (hs20_spp_server_init(&ctx) < 0) {
		xml_node_deinit_ctx(ctx.xml);
		return -1;
	}

	ret = process(&ctx);
	debug_print(&ctx, 1, "process() --> %d", ret);

	xml_node_deinit_ctx(ctx.xml);
	hs20_spp_server_deinit(&ctx);
	if (ctx.debug_log)
		fclose(ctx.debug_log);

	return ret;
}
