#include <signal.h>
#include <getopt.h>
#include <errno.h>

#include <osmocom/core/signal.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/application.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/telnet_interface.h>
#include <osmocom/vty/logging.h>

#include <osmocom/abis/abis.h>
#include <osmocom/abis/e1_input.h>

#include "storage.h"
#include "recorder.h"

#include "config.h"

static enum osmo_e1cap_capture_mode ts2cap_mode(struct e1inp_ts *ts)
{
	switch (ts->type) {
	case E1INP_TS_TYPE_RAW:
		return OSMO_E1CAP_MODE_RAW;
	case E1INP_TS_TYPE_HDLC:
		return OSMO_E1CAP_MODE_HDLC;
	case E1INP_TS_TYPE_TRAU:
		return OSMO_E1CAP_MODE_TRAU;
	default:
		OSMO_ASSERT(0);
	}
}

static int sig_inp_cbfn(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data)
{
	struct input_signal_data *isd = signal_data;
	struct e1_recorder_line *rline;

	OSMO_ASSERT(subsys == SS_L_INPUT);
	OSMO_ASSERT(isd->line && isd->line->num < ARRAY_SIZE(g_recorder.line));

	switch (signal) {
	case S_L_INP_LINE_ALARM:
		LOGP(DMAIN, LOGL_NOTICE, "Line %u: ALARM\n", isd->line->num);
		rline = &g_recorder.line[isd->line->num];
		rline->has_alarm = true;
		break;
	case S_L_INP_LINE_NOALARM:
		LOGP(DMAIN, LOGL_NOTICE, "Line %u: NOALARM\n", isd->line->num);
		rline = &g_recorder.line[isd->line->num];
		rline->has_alarm = false;
		break;
	}
	return 0;
}

/* receive a raw message frome the E1 timeslot */
void e1ts_raw_recv(struct e1inp_ts *ts, struct msgb *msg)
{
	struct e1_recorder_line *rline = &g_recorder.line[ts->line->num];
	enum osmo_e1cap_capture_mode cap_mode = ts2cap_mode(ts);
	int rc;

	if (rline->has_alarm) {
		DEBUGP(DMAIN, "Skipping storage as line %u is in ALARM\n", ts->line->num);
		return;
	}

	/* FIXME: special processing of TFP and PGSL */

	rc = e1frame_store(ts, msg, cap_mode);
	if (rc < 0) {
		LOGP(DMAIN, LOGL_FATAL, "Error writing E1/T1 frame to disk\n");
		exit(1);
	}

	if (rline->mirror.enabled) {
		struct e1inp_line *other_line =
				e1inp_line_find(rline->mirror.line_nr);
		struct e1inp_ts *other_ts;
		other_ts = &other_line->ts[ts->num-1];
		if (!other_ts) {
			msgb_free(msg);
			return;
		}
		/* forward data to destination line */
		OSMO_ASSERT(other_ts->type == ts->type);
		msgb_enqueue(&other_ts->raw.tx_queue, msg);
	} else
		msgb_free(msg);
}

static int inp_sig_cb(unsigned int subsys, unsigned int signal,
		      void *handler_data, void *signal_data)
{
	OSMO_ASSERT(subsys == SS_L_INPUT);

	/* FIXME */

	return 0;
}

static const struct log_info_cat recorder_categories[] = {
	[DMAIN] = {
		.name = "MAIN",
		.description = "Osmocom E1 Recorder",
		.enabled = 1, .loglevel = LOGL_DEBUG,
	},
};
static struct log_info info = {
	.cat = recorder_categories,
	.num_cat = ARRAY_SIZE(recorder_categories),
};

struct vty_app_info vty_info = {
	.name = "osmo-e1-recorder",
	.version = PACKAGE_VERSION,
	.copyright = "(C) 2016-2019 by Harald Welte <laforge@gnumonks.org>\n",
};

static void *rec_tall_ctx;
struct e1_recorder g_recorder;
static char *g_config_file = "osmo-e1-recorder.cfg";

static void signal_handler(int signo)
{
	switch (signo) {
	case SIGHUP:
		storage_close();
		break;
	case SIGUSR1:
		talloc_report(rec_tall_ctx, stderr);
		break;
	}
}

static void print_help(void)
{
	printf( "  -h --help		This help\n"
		"  -V --version		Print version of the program\n"
		"  -c --config FILE	Specify configuration file\n"
		);
}

static void handle_options(int argc, char **argv)
{
	while (1) {
		int option_index = 0, c;
		static const struct option long_options[] = {
			{ "config-file", 1, 0, 'c' },
			{ "help", 0, 0, 'h' },
			{ "version", 0, 0, 'V' },
			{ 0, 0, 0, 0 }
		};

		c = getopt_long(argc, argv, "c:hV",
				long_options, &option_index);
		if (c == -1)
			break;

		switch (c) {
		case 'c':
			g_config_file = optarg;
			break;
		case 'h':
			print_help();
			exit(0);
			break;
		case 'V':
			print_version(1);
			exit(0);
			break;
		}
	}

	if (argc > optind) {
		fprintf(stderr, "Unsupported positional arguments on command line\n");
		exit(2);
	}
}

int main(int argc, char **argv)
{
	int rc;

	rec_tall_ctx = talloc_named_const(NULL, 0, "recorder");

	osmo_init_logging2(rec_tall_ctx, &info);
	vty_init(&vty_info);
	logging_vty_add_cmds();
	osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL);
	libosmo_abis_init(rec_tall_ctx);
	e1inp_vty_init();
	recorder_vty_init();

	signal(SIGHUP, &signal_handler);
	signal(SIGUSR1, &signal_handler);

	handle_options(argc, argv);

	osmo_signal_register_handler(SS_L_INPUT, sig_inp_cbfn, NULL);

	rc = vty_read_config_file(g_config_file, NULL);
	if (rc < 0) {
		fprintf(stderr, "Cannot parse configuration file '%s': %s\n", g_config_file,
			strerror(errno));
		exit(1);
	}

	/* start telne tafte reading config for vty_get_bind_adr() */
	telnet_init_default(rec_tall_ctx, NULL, 4444);

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