#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>

#include <osmocom/core/linuxlist.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/select.h>
#include <osmocom/core/application.h>
#include <osmocom/gsm/gsup.h>

#include <openbsc/gprs_gsup_client.h>
#include <openbsc/debug.h>

static struct gprs_gsup_client *g_gc;


/***********************************************************************
 * IMSI Operation
 ***********************************************************************/
static LLIST_HEAD(g_imsi_ops);

struct imsi_op_stats {
	uint32_t num_alloc;
	uint32_t num_released;
	uint32_t num_rx_success;
	uint32_t num_rx_error;
	uint32_t num_timeout;
};

enum imsi_op_type {
	IMSI_OP_SAI,
	IMSI_OP_LU,
	IMSI_OP_ISD,
	_NUM_IMSI_OP
};

static const struct value_string imsi_op_names[] = {
	{ IMSI_OP_SAI, "SAI" },
	{ IMSI_OP_LU, "LU" },
	{ IMSI_OP_ISD, "ISD" },
	{ 0, NULL }
};

static struct imsi_op_stats imsi_op_stats[_NUM_IMSI_OP];

struct imsi_op {
	struct llist_head list;
	char imsi[17];
	enum imsi_op_type type;
	struct osmo_timer_list timer;
};

static struct imsi_op *imsi_op_find(const char *imsi,
			     enum imsi_op_type type)
{
	struct imsi_op *io;

	llist_for_each_entry(io, &g_imsi_ops, list) {
		if (!strcmp(io->imsi, imsi) && io->type == type)
			return io;
	}
	return NULL;
}

static void imsi_op_timer_cb(void *data);

static struct imsi_op *imsi_op_alloc(void *ctx, const char *imsi,
				enum imsi_op_type type)
{
	struct imsi_op *io;

	if (imsi_op_find(imsi, type))
		return NULL;

	io = talloc_zero(ctx, struct imsi_op);
	strncpy(io->imsi, imsi, sizeof(io->imsi));
	io->imsi[sizeof(io->imsi)-1] = '\0';
	io->type = type;
	io->timer.cb = imsi_op_timer_cb;
	io->timer.data = io;
	llist_add(&io->list, &g_imsi_ops);
	imsi_op_stats[type].num_alloc++;

	return io;
}

static void imsi_op_release(struct imsi_op *io)
{
	osmo_timer_del(&io->timer);
	llist_del(&io->list);
	imsi_op_stats[io->type].num_released++;
	talloc_free(io);
}

static void imsi_op_timer_cb(void *data)
{
	struct imsi_op *io = data;
	printf("%s: Timer expiration\n", io->imsi);
	imsi_op_stats[io->type].num_timeout++;
	imsi_op_release(io);
}

/* allocate + generate + send Send-Auth-Info */
int req_auth_info(const char *imsi)
{
	struct imsi_op *io = imsi_op_alloc(g_gc, imsi, IMSI_OP_SAI);
	struct osmo_gsup_message gsup = {0};
	struct msgb *msg = msgb_alloc_headroom(1200, 200, __func__);

	strncpy(gsup.imsi, io->imsi, sizeof(gsup.imsi));
	gsup.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST;

	osmo_gsup_encode(msg, &gsup);

	return gprs_gsup_client_send(g_gc, msg);
}

/* allocate + generate + send Send-Auth-Info */
int req_loc_upd(const char *imsi)
{
	struct imsi_op *io = imsi_op_alloc(g_gc, imsi, IMSI_OP_LU);
	struct osmo_gsup_message gsup = {0};
	struct msgb *msg = msgb_alloc_headroom(1200, 200, __func__);

	strncpy(gsup.imsi, io->imsi, sizeof(gsup.imsi));
	gsup.message_type = OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST;

	osmo_gsup_encode(msg, &gsup);

	return gprs_gsup_client_send(g_gc, msg);
}

int resp_isd(struct imsi_op *io)
{
	struct osmo_gsup_message gsup = {0};
	struct msgb *msg = msgb_alloc_headroom(1200, 200, __func__);

	strncpy(gsup.imsi, io->imsi, sizeof(gsup.imsi));
	gsup.message_type = OSMO_GSUP_MSGT_INSERT_DATA_RESULT;

	osmo_gsup_encode(msg, &gsup);

	imsi_op_release(io);

	return gprs_gsup_client_send(g_gc, msg);
}

/* receive an incoming GSUP message */
static void imsi_op_rx_gsup(struct imsi_op *io, const struct osmo_gsup_message *gsup)
{
	int is_error = 0;

	if (OSMO_GSUP_IS_MSGT_ERROR(gsup->message_type)) {
		imsi_op_stats[io->type].num_rx_error++;
		is_error = 1;
	} else
		imsi_op_stats[io->type].num_rx_success++;

	switch (io->type) {
	case IMSI_OP_SAI:
		printf("%s; SAI Response%s\n", io->imsi, is_error ? ": ERROR" : "");
		/* now that we have auth tuples, request LU */
		req_loc_upd(io->imsi);
		imsi_op_release(io);
		break;
	case IMSI_OP_LU:
		printf("%s; LU Response%s\n", io->imsi, is_error ? ": ERROR" : "");
		imsi_op_release(io);
		break;
	case IMSI_OP_ISD:
		printf("%s; ISD Request%s\n", io->imsi, is_error ? ": ERROR" : "");
		resp_isd(io);
		break;
	default:
		printf("%s: Unknown\n", io->imsi);
		imsi_op_release(io);
		break;
	}
}

static int op_type_by_gsup_msgt(enum osmo_gsup_message_type msg_type)
{
	switch (msg_type) {
	case OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT:
	case OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR:
		return IMSI_OP_SAI;
	case OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT:
	case OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR:
		return IMSI_OP_LU;
	case OSMO_GSUP_MSGT_INSERT_DATA_REQUEST:
		return IMSI_OP_ISD;
	default:
		printf("Unknown GSUP msg_type %u\n", msg_type);
		return -1;
	}
}

static int gsupc_read_cb(struct gprs_gsup_client *gsupc, struct msgb *msg)
{
	struct osmo_gsup_message gsup_msg = {0};
	struct imsi_op *io;
	int rc;

	DEBUGP(DGPRS, "Rx GSUP %s\n", osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));

	rc = osmo_gsup_decode(msgb_l2(msg), msgb_l2len(msg), &gsup_msg);
	if (rc < 0)
		return rc;

	if (!gsup_msg.imsi[0])
		return -1;

	rc = op_type_by_gsup_msgt(gsup_msg.message_type);
	if (rc < 0)
		return rc;

	switch (rc) {
	case IMSI_OP_SAI:
	case IMSI_OP_LU:
		io = imsi_op_find(gsup_msg.imsi, rc);
		if (!io)
			return -1;
		break;
	case IMSI_OP_ISD:
		/* ISD is an inbound transaction */
		io = imsi_op_alloc(g_gc, gsup_msg.imsi, IMSI_OP_ISD);
		break;
	}

	imsi_op_rx_gsup(io, &gsup_msg);
	msgb_free(msg);

	return 0;
}

static void print_report(void)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(imsi_op_stats); i++) {
		struct imsi_op_stats *st = &imsi_op_stats[i];
		const char *name = get_value_string(imsi_op_names, i);
		printf("%s: %u alloc, %u released, %u success, %u error , %u tout\n",
			name, st->num_alloc, st->num_released, st->num_rx_success,
			st->num_rx_error, st->num_timeout);
	}
}

static void sig_cb(int sig)
{
	switch (sig) {
	case SIGINT:
		print_report();
		exit(0);
		break;
	}
}

void *tall_bsc_ctx = NULL;

/* default categories */
static struct log_info_cat gprs_categories[] = {
	[DGPRS] = {
		.name = "DGPRS",
		.description = "GPRS Packet Service",
		.enabled = 1, .loglevel = LOGL_INFO,
	},
};

static const struct log_info gprs_log_info = {
	.cat = gprs_categories,
	.num_cat = ARRAY_SIZE(gprs_categories),
};

int main(int argc, char **argv)
{
	unsigned long long i;
	char *server_host = "127.0.0.1";
	uint16_t server_port = 2222;

	osmo_init_logging(&gprs_log_info);

	g_gc = gprs_gsup_client_create(server_host, server_port,
					gsupc_read_cb, NULL);


	signal(SIGINT, sig_cb);

	for (i = 0; i < 10000; i++) {
		unsigned long long imsi = 901790000000000 + i;
		char imsi_buf[17];
		snprintf(imsi_buf, sizeof(imsi_buf), "%015llu", imsi);
		req_auth_info(imsi_buf);
		osmo_select_main(0);
	}

	while (1) {
		osmo_select_main(0);
	}

	print_report();
	exit(0);
}
