#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 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 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 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 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 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 = 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);
}
