#include <stdio.h>
#include <signal.h>
#include <osmocom/core/talloc.h>
#include <string.h>
#include <unistd.h>
#include <osmocom/abis/abis.h>
#include <osmocom/abis/e1_input.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/application.h>
#include <osmocom/abis/ipaccess.h>
#include <osmocom/gsm/protocol/gsm_12_21.h>
#include <osmocom/gsm/ipa.h>

static void *tall_test;
static struct e1inp_sign_link *oml_sign_link, *rsl_sign_link;

#define DBTSTEST 0

struct log_info_cat bts_test_cat[] = {
	[DBTSTEST] = {
		.name = "DBTSTEST",
		.description = "BTS-mode test",
		.color = "\033[1;35m",
		.enabled = 1, .loglevel = LOGL_NOTICE,
	},
};

const struct log_info bts_test_log_info = {
	.filter_fn = NULL,
	.cat = bts_test_cat,
	.num_cat = ARRAY_SIZE(bts_test_cat),
};

enum bts_state_machine {
	BTS_TEST_OML_SIGN_LINK_DOWN	= 0,
	BTS_TEST_OML_SIGN_LINK_UP,
	BTS_TEST_OML_WAIT_SW_ACT_ACK,
};

static struct osmo_fd bts_eventfd;
static int eventfds[2];

static enum bts_state_machine bts_state = BTS_TEST_OML_SIGN_LINK_DOWN;

static struct e1inp_sign_link *
sign_link_up(void *unit, struct e1inp_line *line, enum e1inp_sign_type type)
{
	struct e1inp_sign_link *sign_link = NULL;

	switch(type) {
	case E1INP_SIGN_OML:
		LOGP(DBTSTEST, LOGL_NOTICE, "OML link up request received.\n");

		e1inp_ts_config_sign(e1inp_line_ipa_oml_ts(line), line);
		sign_link = oml_sign_link =
			e1inp_sign_link_create(e1inp_line_ipa_oml_ts(line),
						E1INP_SIGN_OML, NULL, 255, 0);
		if (!oml_sign_link) {
			LOGP(DBTSTEST, LOGL_ERROR,
				"cannot create OML sign link\n");
		}
		if (oml_sign_link) {
			unsigned int event_type = 0;

			/* tell GSM 12.21 that we're ready via our eventfd. */
			if (write(eventfds[1], &event_type,
						sizeof(unsigned int)) < 0) {
				LOGP(DBTSTEST, LOGL_ERROR, "cannot write "
							   "event fd.\n");
			}
			/* Now we can send OML messages to the BSC. */
			bts_state = BTS_TEST_OML_SIGN_LINK_UP;
		}
		e1inp_ipa_bts_rsl_connect_n(line, "127.0.0.1", IPA_TCP_PORT_RSL, 0);
		break;
	case E1INP_SIGN_RSL:
		LOGP(DBTSTEST, LOGL_NOTICE, "RSL link up request received.\n");

		e1inp_ts_config_sign(e1inp_line_ipa_rsl_ts(line, 0), line);

		sign_link = rsl_sign_link =
			e1inp_sign_link_create(e1inp_line_ipa_rsl_ts(line, 0),
						E1INP_SIGN_RSL, NULL, 0, 0);
		if (!rsl_sign_link) {
			LOGP(DBTSTEST, LOGL_ERROR,
				"cannot create RSL sign link\n");
		}
		break;
	default:
		return NULL;
	}
	if (sign_link)
		LOGP(DBTSTEST, LOGL_NOTICE, "signal link has been set up.\n");

	return sign_link;
}

static void sign_link_down(struct e1inp_line *line)
{
	LOGP(DBTSTEST, LOGL_NOTICE, "signal link has been closed\n");
	e1inp_sign_link_destroy(oml_sign_link);
	e1inp_sign_link_destroy(rsl_sign_link);
}

static int abis_nm_rcvmsg_fom(struct msgb *msg)
{
	struct abis_om_fom_hdr *foh = msgb_l3(msg);
	uint8_t mt = foh->msg_type;
	int ret = 0;

	switch (mt) {
	case NM_MT_SW_ACT_REQ_ACK:  /* SW activate request ACK from BSC. */
		LOGP(DBTSTEST, LOGL_NOTICE, "Receive SW Act Req ACK\n");
		break;
	default:
		LOGP(DBTSTEST, LOGL_ERROR, "unknown OML message\n");
		break;
	}
	return ret;
}

static int abis_nm_rcvmsg(struct msgb *msg)
{
	int ret = 0;
	struct abis_om_hdr *oh = msgb_l2(msg);

	msg->l3h = (unsigned char *)oh + sizeof(*oh);
	switch (oh->mdisc) {
	case ABIS_OM_MDISC_FOM:
		ret = abis_nm_rcvmsg_fom(msg);
		break;
	default:
		LOGP(DBTSTEST, LOGL_ERROR, "unknown OML message\n");
	break;
	}
	return ret;
}

static int sign_link(struct msgb *msg)
{
	int ret = 0;
	struct e1inp_sign_link *link = msg->dst;

	switch(link->type) {
	case E1INP_SIGN_OML:
		LOGP(DBTSTEST, LOGL_NOTICE, "OML message received.\n");
		ret = abis_nm_rcvmsg(msg);
		break;
	case E1INP_SIGN_RSL:
		LOGP(DBTSTEST, LOGL_NOTICE, "RSL message received.\n");
		break;
	default:
		LOGP(DBTSTEST, LOGL_ERROR, "Unknown signalling message.\n");
		break;
	}
	msgb_free(msg);
	return ret;
}

static void fill_om_hdr(struct abis_om_hdr *oh, uint8_t len)
{
	oh->mdisc = ABIS_OM_MDISC_FOM;
	oh->placement = ABIS_OM_PLACEMENT_ONLY;
	oh->sequence = 0;
	oh->length = len;
}

static void fill_om_fom_hdr(struct abis_om_hdr *oh, uint8_t len,
			    uint8_t msg_type, uint8_t obj_class,
			    uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr)
{
	struct abis_om_fom_hdr *foh = (struct abis_om_fom_hdr *) oh->data;

	fill_om_hdr(oh, len+sizeof(*foh));
	foh->msg_type = msg_type;
	foh->obj_class = obj_class;
	foh->obj_inst.bts_nr = bts_nr;
	foh->obj_inst.trx_nr = trx_nr;
	foh->obj_inst.ts_nr = ts_nr;
}

#define OM_ALLOC_SIZE		1024
#define OM_HEADROOM_SIZE	128

static struct msgb *nm_msgb_alloc(void)
{
        return msgb_alloc_headroom(OM_ALLOC_SIZE, OM_HEADROOM_SIZE, "BTS/test");
}

static int abis_nm_sw_act_req(struct e1inp_sign_link *sign_link,
			      uint8_t obj_class,
			      uint8_t i1, uint8_t i2, uint8_t i3,
			      uint8_t *attr, int att_len)
{
	struct abis_om_hdr *oh;
	struct msgb *msg = nm_msgb_alloc();
	uint8_t msgtype = NM_MT_SW_ACT_REQ;

	oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
	fill_om_fom_hdr(oh, att_len, msgtype, obj_class, i1, i2, i3);

	if (attr) {
		uint8_t *ptr = msgb_put(msg, att_len);
		memcpy(ptr, attr, att_len);
	}
	msg->dst = sign_link;
	return abis_sendmsg(msg);
}

static int test_bts_gsm_12_21_cb(struct osmo_fd *ofd, unsigned int what)
{
	int ret, event_type;
	struct ipaccess_unit *unit = ofd->data;

	if (read(eventfds[0], &event_type, sizeof(unsigned int)) < 0) {
		LOGP(DBTSTEST, LOGL_ERROR, "error receiving event\n");
		return 0;
	}

	switch(bts_state) {
	case BTS_TEST_OML_SIGN_LINK_DOWN:
		/* Do nothing until OML link becomes ready. */
		break;
	case BTS_TEST_OML_SIGN_LINK_UP:
		/* OML link is up, send SW ACT REQ. */
		ret = abis_nm_sw_act_req(oml_sign_link, 0,
					 unit->bts_id,
					 unit->trx_id,
					 0, NULL, 0);
		if (ret < 0) {
			LOGP(DBTSTEST, LOGL_ERROR, "cannot send SW ACT REQ\n");
			break;
		}
		bts_state = BTS_TEST_OML_WAIT_SW_ACT_ACK;
		break;
	case BTS_TEST_OML_WAIT_SW_ACT_ACK:
		/* ... things should continue after this. */
		break;
	}
	return 0;
}

static struct e1inp_line *line;

static void sighandler(int foo)
{
	e1inp_line_put2(line, "ctor");
	exit(EXIT_SUCCESS);
}

int main(void)
{
	struct ipaccess_unit bts_dev_info = {
		.site_id	= 1801,
		.bts_id		= 0,
		.trx_id		= 0,
		.unit_name	= "testBTS",
		.equipvers	= "0.1",
		.swversion	= "0.1",
		.mac_addr	= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
		.location1	= "testBTS",
		.location2	= "testBTS",
		.serno		= "",
	};

	tall_test = talloc_named_const(NULL, 1, "e1inp_test");
	libosmo_abis_init(tall_test);
	msgb_talloc_ctx_init(tall_test, 0);
	osmo_init_logging2(tall_test, &bts_test_log_info);

	struct e1inp_line_ops ops = {
		.cfg = {
			.ipa = {
				.role	= E1INP_LINE_R_BTS,
				.addr	= "127.0.0.1",
				.dev	= &bts_dev_info,
			},
		},
		.sign_link_up	= sign_link_up,
		.sign_link_down	= sign_link_down,
		.sign_link	= sign_link,
	};

#define LINENR 0

	if (signal(SIGINT, sighandler) == SIG_ERR ||
	    signal(SIGTERM, sighandler) == SIG_ERR) {
		perror("Cannot set sighandler");
		exit(EXIT_FAILURE);
	}

	line = e1inp_line_create(LINENR, "ipa");
	if (line == NULL) {
		LOGP(DBTSTEST, LOGL_ERROR, "problem enabling E1 line\n");
		exit(EXIT_FAILURE);
	}
	e1inp_line_bind_ops(line, &ops);

	if (e1inp_line_update(line) < 0) {
		LOGP(DBTSTEST, LOGL_ERROR, "problem enabling E1 line\n");
		exit(EXIT_FAILURE);
	}

	LOGP(DBTSTEST, LOGL_NOTICE, "entering main loop\n");

	if (pipe(eventfds) < 0) {
		LOGP(DBTSTEST, LOGL_ERROR, "cannot create pipe fds\n");
		exit(EXIT_FAILURE);
	}
	osmo_fd_setup(&bts_eventfd, eventfds[0], OSMO_FD_READ, test_bts_gsm_12_21_cb, &bts_dev_info, 0);
	if (osmo_fd_register(&bts_eventfd) < 0) {
		LOGP(DBTSTEST, LOGL_ERROR, "could not register event fd\n");
		exit(EXIT_FAILURE);
	}

	while (1) {
		osmo_select_main(0);
	}
	return 0;
}
