#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/core/utils.h>
#include <osmocom/core/logging.h>
#include <osmocom/gsm/gsup.h>

#include <osmocom/gsupclient/gsup_client.h>

static struct osmo_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);
	OSMO_STRLCPY_ARRAY(io->imsi, imsi);
	io->type = type;
	osmo_timer_setup(&io->timer, imsi_op_timer_cb, 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 */
static 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__);
	int rc;

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

	rc = osmo_gsup_encode(msg, &gsup);
	if (rc < 0) {
		printf("%s: encoding failure (%s)\n", imsi, strerror(-rc));
		return rc;
	}

	return osmo_gsup_client_send(g_gc, msg);
}

/* allocate + generate + send Send-Auth-Info */
static 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__);
	int rc;

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

	rc = osmo_gsup_encode(msg, &gsup);
	if (rc < 0) {
		printf("%s: encoding failure (%s)\n", imsi, strerror(-rc));
		return rc;
	}

	return osmo_gsup_client_send(g_gc, msg);
}

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

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

	rc = osmo_gsup_encode(msg, &gsup);
	if (rc < 0) {
		printf("%s: encoding failure (%s)\n", io->imsi, strerror(-rc));
		return rc;
	}

	imsi_op_release(io);

	return osmo_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, rc;

	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 */
		rc = req_loc_upd(io->imsi);
		if (rc < 0)
			printf("Failed to request Location Update for %s\n", 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" : "");
		rc = resp_isd(io);
		if (rc < 0)
			printf("Failed to insert subscriber data for %s\n", io->imsi);
		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 osmo_gsup_client *gsupc, struct msgb *msg)
{
	struct osmo_gsup_message gsup_msg = {0};
	struct imsi_op *io = NULL;
	int rc;

	DEBUGP(DLGSUP, "Rx GSUP %s\n", msgb_hexdump(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);
		break;
	case IMSI_OP_ISD:
		/* ISD is an inbound transaction */
		io = imsi_op_alloc(g_gc, gsup_msg.imsi, IMSI_OP_ISD);
		break;
	}
	if (!io)
		return -1;

	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;
	}
}

/* default categories */
static struct log_info_cat default_categories[] = {
};

static const struct log_info gsup_test_client_log_info = {
	.cat = default_categories,
	.num_cat = ARRAY_SIZE(default_categories),
};

int main(int argc, char **argv)
{
	unsigned long long i;
	char *server_host = "127.0.0.1";
	uint16_t server_port = OSMO_GSUP_PORT;
	void *ctx = talloc_named_const(NULL, 0, "gsup_test_client");

	osmo_init_logging2(ctx, &gsup_test_client_log_info);

	g_gc = osmo_gsup_client_create(ctx, "GSUPTEST", 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] = { 0 };
		int rc;

		snprintf(imsi_buf, sizeof(imsi_buf), "%015llu", imsi);
		rc = req_auth_info(imsi_buf);
		if (rc < 0)
			printf("Failed to request Auth Info for %s\n", imsi_buf);

		osmo_select_main(0);
	}

	while (1) {
		osmo_select_main(0);
	}

	print_report();
	exit(0);
}
