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

#include "recorder.h"

#define LINE_STR "Configure Recording for given Line\nE1/T1 Line Number\n"

DEFUN(cfg_recorder, cfg_recorder_cmd,
	"recorder",
	"Configuration of E1 Recorder\n")
{
	vty->node = RECORDER_NODE;
	return CMD_SUCCESS;
}

DEFUN(cfg_rec_line_ts_mode, cfg_rec_line_ts_mode_cmd,
	"line <0-255> ts <0-31> mode (none|signalling|trau|raw)",
	LINE_STR
	"E1/T1 Timeslot Number\n"
	"E1/T1 Timeslot Number\n"
	"Recording Mode\n"
	"No recording\n"
	"Signalling Data (HDLC)\n"
	"TRAU Frames\n"
	"Raw Data\n")
{
	int line_nr = atoi(argv[0]);
	int ts_nr = atoi(argv[1]);
	int mode = get_string_value(e1inp_ts_type_names, argv[2]);
	struct e1inp_line *line;
	struct e1inp_ts *ts;

	if (mode < 0) {
		vty_out(vty, "Cannot parse mode %s%s", argv[2], VTY_NEWLINE);
		return CMD_WARNING;
	}

	line = e1inp_line_find(line_nr);
	if (!line) {
		vty_out(vty, "Cannot find line %d%s", line_nr, VTY_NEWLINE);
		return CMD_WARNING;
	}
	if (ts_nr >= line->num_ts) {
		vty_out(vty, "Timeslot %d is too large%s", ts_nr, VTY_NEWLINE);
		return CMD_WARNING;
	}
	ts = &line->ts[ts_nr];

	switch (mode) {
	case E1INP_TS_TYPE_NONE:
		/* TOOD: have eqinp_ts_config_none ? */
		ts->type = E1INP_TS_TYPE_NONE;
		break;
	case E1INP_TS_TYPE_SIGN:
		e1inp_ts_config_sign(ts, line);
		break;
	case E1INP_TS_TYPE_RAW:
		e1inp_ts_config_raw(ts, line, &e1ts_raw_recv);
		break;
	}

	/* notify driver of change */
	e1inp_line_update(line);

	return CMD_SUCCESS;
}

DEFUN(cfg_rec_line_mirror, cfg_rec_line_mirror_cmd,
	"line <0-255> mirror <0-255>",
	LINE_STR "Mirror this line to another line\n"
	"E1/T1 Line Number\n")
{
	uint8_t line_nr = atoi(argv[0]);
	uint8_t peer_nr = atoi(argv[1]);
	struct e1_recorder_line *line = &g_recorder.line[line_nr];
	struct e1_recorder_line *peer = &g_recorder.line[peer_nr];
	/* look up morror peer and enable mirror flag on peer */
	if (peer->mirror.enabled &&
	    peer->mirror.line_nr != line_nr) {
		vty_out(vty, "Peer line %u already part of another mirror%s",
			peer_nr, VTY_NEWLINE);
		return CMD_WARNING;
	}
	peer->mirror.enabled = true;
	peer->mirror.line_nr = line_nr;
	/* enable mirror flag of current line */
	if (line->mirror.enabled &&
	    line->mirror.line_nr != peer_nr) {
		vty_out(vty, "Line %u already part of another mirror%s",
			line_nr, VTY_NEWLINE);
		return CMD_WARNING;
	}
	line->mirror.enabled = true;
	line->mirror.line_nr = peer_nr;
	return CMD_SUCCESS;
}

DEFUN(cfg_rec_no_line_mirror, cfg_rec_no_line_mirror_cmd,
	"no line <0-255> mirror",
	LINE_STR "Mirror this line to another line\n"
	"E1/T1 Line Number\n")
{
	uint8_t line_nr = atoi(argv[0]);
	struct e1_recorder_line *line = &g_recorder.line[line_nr];
	struct e1_recorder_line *peer;

	if (!line->mirror.enabled)
		return CMD_WARNING;
	/* look up morror peer (if any) and disable mirror flag on peer */
	peer = &g_recorder.line[line->mirror.line_nr];
	if (peer->mirror.enabled) {
		peer->mirror.enabled = false;
		peer->mirror.line_nr = 0;
	}
	/* dsiable mirror flag of current line */
	if (line->mirror.enabled){
		line->mirror.enabled = false;
		line->mirror.line_nr = 0;
	}
	return CMD_SUCCESS;
}


DEFUN(cfg_rec_save_path, cfg_rec_save_path_cmd,
	"storage-path PATH",
	"Configure the directory for storing recordings\n"
	"Directory to which recordings are stored\n")
{
	osmo_talloc_replace_string(NULL, &g_recorder.storage_path, argv[0]);
	return CMD_SUCCESS;
}

DEFUN(cfg_rec_file_size, cfg_rec_file_size_cmd,
	"file-size-mb <1-9999999>",
	"Configure the maximum file size before starting new file\n"
	"Megabytes\n")
{
	g_recorder.max_file_size_mb = atoi(argv[0]);
	return CMD_SUCCESS;
}

static void config_write_recorder_line(struct vty *vty, unsigned int lnr)
{
	struct e1inp_line *line = e1inp_line_find(lnr);
	struct e1_recorder_line *rline = &g_recorder.line[lnr];
	unsigned int i;

	if (rline->mirror.enabled) {
		vty_out(vty, " line %u mirror %u%s",
			lnr, rline->mirror.line_nr, VTY_NEWLINE);
	}

	if (!line)
		return;

	for (i = 0; i < line->num_ts; i++) {
		struct e1inp_ts *ts = &line->ts[i];
	}
}

static int config_write_recorder(struct vty *vty)
{
	unsigned int i;

	vty_out(vty, "recorder%s", VTY_NEWLINE);
	vty_out(vty, " file-size-mb %u%s", g_recorder.max_file_size_mb,
		VTY_NEWLINE);
	vty_out(vty, " storage-path %s%s", g_recorder.storage_path,
		VTY_NEWLINE);
	for (i = 0; i < 255; i++) {
		config_write_recorder_line(vty, i);
	}

	return 0;
}

static struct cmd_node cfg_recorder_node = {
	RECORDER_NODE,
	"%s(config-recorder)# ",
	1,
};

void recorder_vty_init(void)
{
	install_element(CONFIG_NODE, &cfg_recorder_cmd);

	install_node(&cfg_recorder_node, config_write_recorder);
	install_element(RECORDER_NODE, &cfg_rec_line_ts_mode_cmd);
	install_element(RECORDER_NODE, &cfg_rec_line_mirror_cmd);
	install_element(RECORDER_NODE, &cfg_rec_no_line_mirror_cmd);
	install_element(RECORDER_NODE, &cfg_rec_save_path_cmd);
	install_element(RECORDER_NODE, &cfg_rec_file_size_cmd);
}
