/*
 * Copyright (C) 2013 Thomas Tsou <tom@tsou.cc>
 *
 * SPDX-License-Identifier: LGPL-2.1+
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "Transceiver.h"
#include "radioDevice.h"
#include "Utils.h"

#include <time.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <sched.h>
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <sys/signalfd.h>

#include <GSMCommon.h>
#include <Logger.h>

extern "C" {
#include <osmocom/core/talloc.h>
#include <osmocom/core/application.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/stats.h>
#include <osmocom/vty/logging.h>
#include <osmocom/vty/ports.h>
#include <osmocom/vty/misc.h>
#include <osmocom/vty/telnet_interface.h>
#include <osmocom/ctrl/control_vty.h>
#include <osmocom/ctrl/ports.h>
#include <osmocom/ctrl/control_if.h>
#include <osmocom/vty/stats.h>
#include <osmocom/vty/command.h>
#include <osmocom/vty/cpu_sched_vty.h>

#include "convolve.h"
#include "convert.h"
#include "trx_vty.h"
#include "debug.h"
#include "osmo_signal.h"
#include "trx_rate_ctr.h"
}

#define DEFAULT_CONFIG_FILE	"osmo-trx.cfg"

#define charp2str(a) ((a) ? std::string(a) : std::string(""))

static char* config_file = (char*)DEFAULT_CONFIG_FILE;

struct osmo_fd signal_ofd;
volatile bool gshutdown = false;

static void *tall_trx_ctx;
static struct trx_ctx *g_trx_ctx;
static struct ctrl_handle *g_ctrlh;

static RadioDevice *usrp;
static RadioInterface *radio;

/* adjusts read timestamp offset to make the viterbi equalizer happy by including the start tail bits */
template <typename B>
class rif_va_wrapper : public B {
	bool use_va;

    public:
	template <typename... Args>
	rif_va_wrapper(bool use_va, Args &&...args) : B(std::forward<Args>(args)...), use_va(use_va)
	{
	}
	bool start() override
	{
		auto rv = B::start();
		B::readTimestamp -= use_va ? 20 : 0;
		return rv;
	};
};

/* Create radio interface
 *     The interface consists of sample rate changes, frequency shifts,
 *     channel multiplexing, and other conversions. The transceiver core
 *     accepts input vectors sampled at multiples of the GSM symbol rate.
 *     The radio interface connects the main transceiver with the device
 *     object, which may be operating some other rate.
 */
RadioInterface *makeRadioInterface(struct trx_ctx *trx,
                                   RadioDevice *usrp, int type)
{
	RadioInterface *radio = NULL;

	switch (type) {
	case RadioDevice::NORMAL:
		radio = new rif_va_wrapper<RadioInterface>(trx->cfg.use_va, usrp, trx->cfg.tx_sps, trx->cfg.rx_sps,
							   trx->cfg.num_chans);
		break;
	case RadioDevice::RESAMP_64M:
	case RadioDevice::RESAMP_100M:
		radio = new rif_va_wrapper<RadioInterfaceResamp>(trx->cfg.use_va, usrp, trx->cfg.tx_sps,
								 trx->cfg.rx_sps);
		break;
	case RadioDevice::MULTI_ARFCN:
		radio = new rif_va_wrapper<RadioInterfaceMulti>(trx->cfg.use_va, usrp, trx->cfg.tx_sps, trx->cfg.rx_sps,
								trx->cfg.num_chans);
		break;
	default:
		LOG(ALERT) << "Unsupported radio interface configuration";
		return NULL;
	}

	if (!radio->init(type)) {
		LOG(ALERT) << "Failed to initialize radio interface";
		return NULL;
	}

	return radio;
}

/* Callback function to be called every time we receive a signal from TRANSC */
static int transc_sig_cb(unsigned int subsys, unsigned int signal,
		     void *handler_data, void *signal_data)
{
	switch (signal) {
	case S_MAIN_STOP_REQUIRED:
		gshutdown = true;
                break;
	default:
                break;
	}
	return 0;
}

/* Create transceiver core
 *     The multi-threaded modem core operates at multiples of the GSM rate of
 *     270.8333 ksps and consists of GSM specific modulation, demodulation,
 *     and decoding schemes. Also included are the socket interfaces for
 *     connecting to the upper layer stack.
 */
int makeTransceiver(struct trx_ctx *trx, RadioInterface *radio)
{
	VectorFIFO *fifo;

	transceiver = new Transceiver(&trx->cfg, GSM::Time(3,0), radio);
	if (!transceiver->init()) {
		LOG(ALERT) << "Failed to initialize transceiver";
		return -1;
	}

	for (size_t i = 0; i < trx->cfg.num_chans; i++) {
		fifo = radio->receiveFIFO(i);
		if (fifo && transceiver->receiveFIFO(fifo, i))
			continue;

		LOG(ALERT) << "Could not attach FIFO to channel " << i;
		return -1;
	}
	return 0;
}

static void sig_handler(int signo)
{

	if (gshutdown)
		/* We are in the middle of shutdown process, avoid any kind of extra
		   action like printing */
		return;

	fprintf(stderr, "signal %d received\n", signo);
	switch (signo) {
	case SIGINT:
	case SIGTERM:
		fprintf(stderr, "shutting down\n");
		gshutdown = true;
		break;
	case SIGABRT:
		/* in case of abort, we want to obtain a talloc report and
		 * then run default SIGABRT handler, who will generate coredump
		 * and abort the process. abort() should do this for us after we
		 * return, but program wouldn't exit if an external SIGABRT is
		 * received.
		 */
		talloc_report(tall_trx_ctx, stderr);
		talloc_report_full(tall_trx_ctx, stderr);
		signal(SIGABRT, SIG_DFL);
		raise(SIGABRT);
		break;
	case SIGUSR1:
		talloc_report(tall_trx_ctx, stderr);
		talloc_report_full(tall_trx_ctx, stderr);
		break;
	case SIGUSR2:
		talloc_report_full(tall_trx_ctx, stderr);
		break;
	case SIGHUP:
		log_targets_reopen();
	default:
		break;
	}

}

static int signalfd_callback(struct osmo_fd *ofd, unsigned int what)
{
	struct signalfd_siginfo fdsi;
	ssize_t s;

	s = read(ofd->fd, &fdsi, sizeof(struct signalfd_siginfo));
	if (s < 0) {
		LOG(FATAL) << "Failed to read from signalfd ("<< ofd->fd << "): " << errno;
		gshutdown = true;
		return 0;
	}
	sig_handler(fdsi.ssi_signo);
	return 0;
}

static void setup_signal_handlers()
{
	sigset_t set;
	int sfd;

	signal(SIGABRT, &sig_handler);
	osmo_init_ignore_signals();

	/* Other threads created by this thread (main) will inherit a copy of the
	signal mask. */
	sigemptyset(&set);
	sigaddset(&set, SIGINT);
	sigaddset(&set, SIGTERM);
	sigaddset(&set, SIGUSR1);
	sigaddset(&set, SIGUSR2);
	sigaddset(&set, SIGHUP);
	if (pthread_sigmask(SIG_BLOCK, &set, NULL)) {
		fprintf(stderr, "pthread_sigmask() failed.\n");
		exit(EXIT_FAILURE);
	}

	if ((sfd = signalfd(-1, &set, 0)) == -1) {
		fprintf(stderr, "signalfd() failed (%d).\n", errno);
		exit(EXIT_FAILURE);
	}

	osmo_fd_setup(&signal_ofd, sfd, OSMO_FD_READ, signalfd_callback, NULL, 0);
	if (osmo_fd_register(&signal_ofd) < 0) {
		fprintf(stderr, "osmo_fd_register() failed.\n");
		exit(EXIT_FAILURE);
	}
}

static void print_help()
{
	printf( "Some useful options:\n"
		"  -h, --help			This text\n"
		"  -C, --config			Filename The config file to use\n"
		"  -V, --version		Print the version of OsmoTRX\n"
		"\nVTY reference generation:\n"
		"      --vty-ref-mode MODE	VTY reference generation mode (e.g. 'expert').\n"
		"      --vty-ref-xml		Generate the VTY reference XML output and exit.\n"
		);
}

static void print_deprecated(char opt)
{
	LOG(WARNING) << "Cmd line option '" << opt << "' is deprecated and will be soon removed."
		<< " Please use VTY cfg option instead."
		<< " All cmd line options are already being overridden by VTY options if set.";
}

static void handle_long_options(const char *prog_name, const int long_option)
{
	static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT;

	switch (long_option) {
	case 1:
		vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg);
		if (vty_ref_mode < 0) {
			fprintf(stderr, "%s: Unknown VTY reference generation "
				"mode '%s'\n", prog_name, optarg);
			exit(2);
		}
		break;
	case 2:
		fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n",
			get_value_string(vty_ref_gen_mode_names, vty_ref_mode),
			get_value_string(vty_ref_gen_mode_desc, vty_ref_mode));
		vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode);
		exit(0);
	default:
		fprintf(stderr, "%s: error parsing cmdline options\n", prog_name);
		exit(2);
	}
}

static void handle_options(int argc, char **argv, struct trx_ctx* trx)
{
	int option;
	unsigned int i;
	std::vector<std::string> rx_paths, tx_paths;
	bool rx_paths_set = false, tx_paths_set = false;
	static int long_option = 0;
	static struct option long_options[] = {
		{"help", 0, 0, 'h'},
		{"config", 1, 0, 'C'},
		{"version", 0, 0, 'V'},
		{"vty-ref-mode", 1, &long_option, 1},
		{"vty-ref-xml", 0, &long_option, 2},
		{NULL, 0, 0, 0}
	};

	while ((option = getopt_long(argc, argv, "ha:l:i:j:p:c:dmxgfo:s:b:r:A:R:Set:y:z:C:V", long_options,
		NULL)) != -1) {
		switch (option) {
		case 'h':
			print_help();
			exit(0);
			break;
		case 0:
			handle_long_options(argv[0], long_option);
			break;
		case 'a':
			print_deprecated(option);
			osmo_talloc_replace_string(trx, &trx->cfg.dev_args, optarg);
			break;
		case 'l':
			print_deprecated(option);
			log_set_log_level(osmo_stderr_target, atoi(optarg));
			break;
		case 'i':
			print_deprecated(option);
			osmo_talloc_replace_string(trx, &trx->cfg.remote_addr, optarg);
			break;
		case 'j':
			print_deprecated(option);
			osmo_talloc_replace_string(trx, &trx->cfg.bind_addr, optarg);
			break;
		case 'p':
			print_deprecated(option);
			trx->cfg.base_port = atoi(optarg);
			break;
		case 'c':
			print_deprecated(option);
			trx->cfg.num_chans = atoi(optarg);
			break;
		case 'm':
			print_deprecated(option);
			trx->cfg.multi_arfcn = true;
			break;
		case 'x':
			print_deprecated(option);
			trx->cfg.clock_ref = REF_EXTERNAL;
			break;
		case 'g':
			print_deprecated(option);
			trx->cfg.clock_ref = REF_GPS;
			break;
		case 'f':
			print_deprecated(option);
			trx->cfg.filler = FILLER_DUMMY;
			break;
		case 'o':
			print_deprecated(option);
			trx->cfg.offset = atof(optarg);
			break;
		case 's':
			print_deprecated(option);
			trx->cfg.tx_sps = atoi(optarg);
			break;
		case 'b':
			print_deprecated(option);
			trx->cfg.rx_sps = atoi(optarg);
			break;
		case 'r':
			print_deprecated(option);
			trx->cfg.rtsc = atoi(optarg);
			if (!trx->cfg.egprs) /* Don't override egprs which sets different filler */
				trx->cfg.filler = FILLER_NORM_RAND;
			break;
		case 'A':
			print_deprecated(option);
			trx->cfg.rach_delay = atoi(optarg);
			trx->cfg.filler = FILLER_ACCESS_RAND;
			break;
		case 'R':
			print_deprecated(option);
			trx->cfg.rssi_offset = atof(optarg);
			trx->cfg.force_rssi_offset = true;
			break;
		case 'S':
			print_deprecated(option);
			trx->cfg.swap_channels = true;
			break;
		case 'e':
			print_deprecated(option);
			trx->cfg.egprs = true;
			break;
		case 't':
			print_deprecated(option);
			trx->cfg.sched_rr = atoi(optarg);
			break;
		case 'y':
			print_deprecated(option);
			tx_paths = comma_delimited_to_vector(optarg);
			tx_paths_set = true;
			break;
		case 'z':
			print_deprecated(option);
			rx_paths = comma_delimited_to_vector(optarg);
			rx_paths_set = true;
			break;
		case 'C':
			config_file = optarg;
			break;
		case 'V':
			print_version(1);
			exit(0);
			break;
		default:
			goto bad_config;
		}
	}

	if (argc > optind) {
		LOG(ERROR) << "Unsupported positional arguments on command line";
		goto bad_config;
	}

	/* Cmd line option specific validation & setup */

	if (trx->cfg.num_chans > TRX_CHAN_MAX) {
		LOG(ERROR) << "Too many channels requested, maximum is " <<  TRX_CHAN_MAX;
		goto bad_config;
	}
	if ((tx_paths_set && tx_paths.size() != trx->cfg.num_chans) ||
	    (rx_paths_set && rx_paths.size() != trx->cfg.num_chans)) {
		LOG(ERROR) << "Num of channels and num of Rx/Tx Antennas doesn't match";
		goto bad_config;
	}
	for (i = 0; i < trx->cfg.num_chans; i++) {
		trx->cfg.chans[i].trx = trx;
		trx->cfg.chans[i].idx = i;
		if (tx_paths_set)
			osmo_talloc_replace_string(trx, &trx->cfg.chans[i].tx_path, tx_paths[i].c_str());
		if (rx_paths_set)
			osmo_talloc_replace_string(trx, &trx->cfg.chans[i].rx_path, rx_paths[i].c_str());
	}

	return;

bad_config:
	print_help();
	exit(0);
}

int trx_validate_config(struct trx_ctx *trx)
{
	if (trx->cfg.multi_arfcn && trx->cfg.num_chans > TRX_MCHAN_MAX) {
		LOG(ERROR) << "Unsupported number of channels";
		return -1;
	}

	/* Force 4 SPS for EDGE or multi-ARFCN configurations */
	if ((trx->cfg.egprs || trx->cfg.multi_arfcn) &&
	    (trx->cfg.tx_sps!=4 || trx->cfg.rx_sps!=4)) {
		LOG(ERROR) << "EDGE and Multi-Carrier options require 4 tx and rx sps. Check you config.";
		return -1;
	}

	if (trx->cfg.use_va &&
	    (trx->cfg.egprs || trx->cfg.multi_arfcn || trx->cfg.tx_sps != 4 || trx->cfg.rx_sps != 4)) {
		LOG(ERROR) << "Viterbi equalizer only works for gmsk with 4 tx/rx samples per symbol!";
		return -1;
	}

	return 0;
}

static int set_sched_rr(unsigned int prio)
{
	struct sched_param param;
	int rc;
	memset(&param, 0, sizeof(param));
	param.sched_priority = prio;
	LOG(INFO) << "Setting SCHED_RR priority " << param.sched_priority
		  << ". This setting is DEPRECATED, please use 'policy rr " << param.sched_priority
		  << "' under the 'sched' VTY node instead.";
	rc = sched_setscheduler(getpid(), SCHED_RR, &param);
	if (rc != 0) {
		LOG(ERROR) << "Config: Setting SCHED_RR failed";
		return -1;
	}
	return 0;
}

static void print_simd_info(void)
{
#ifdef HAVE_SSE3
	LOGP(DMAIN, LOGL_INFO, "SSE3 support compiled in");
#ifdef HAVE___BUILTIN_CPU_SUPPORTS
	if (__builtin_cpu_supports("sse3"))
		LOGPC(DMAIN, LOGL_INFO, " and supported by CPU\n");
	else
		LOGPC(DMAIN, LOGL_INFO, ", but not supported by CPU\n");
#else
	LOGPC(DMAIN, LOGL_INFO, ", but runtime SIMD detection disabled\n");
#endif
#endif

#ifdef HAVE_SSE4_1
	LOGP(DMAIN, LOGL_INFO, "SSE4.1 support compiled in");
#ifdef HAVE___BUILTIN_CPU_SUPPORTS
	if (__builtin_cpu_supports("sse4.1"))
		LOGPC(DMAIN, LOGL_INFO, " and supported by CPU\n");
	else
		LOGPC(DMAIN, LOGL_INFO, ", but not supported by CPU\n");
#else
	LOGPC(DMAIN, LOGL_INFO, ", but runtime SIMD detection disabled\n");
#endif
#endif

#ifndef HAVE_ATOMIC_OPS
#pragma message ("Built without atomic operation support. Using Mutex, it may affect performance!")
	LOG(NOTICE) << "Built without atomic operation support. Using Mutex, it may affect performance!";
#endif
}

static void print_config(struct trx_ctx *trx)
{
	unsigned int i;
	std::ostringstream ost("");

	ost << "Config Settings" << std::endl;
	ost << "   Log Level............... " << (unsigned int) osmo_stderr_target->loglevel << std::endl;
	ost << "   Device args............. " << charp2str(trx->cfg.dev_args) << std::endl;
	ost << "   TRX Base Port........... " << trx->cfg.base_port << std::endl;
	ost << "   TRX Address............. " << charp2str(trx->cfg.bind_addr) << std::endl;
	ost << "   GSM BTS Address......... " << charp2str(trx->cfg.remote_addr) << std::endl;
	ost << "   Channels................ " << trx->cfg.num_chans << std::endl;
	ost << "   Tx Samples-per-Symbol... " << trx->cfg.tx_sps << std::endl;
	ost << "   Rx Samples-per-Symbol... " << trx->cfg.rx_sps << std::endl;
	ost << "   EDGE support............ " << trx->cfg.egprs << std::endl;
	ost << "   Extended RACH support... " << trx->cfg.ext_rach << std::endl;
	ost << "   Reference............... " << trx->cfg.clock_ref << std::endl;
	ost << "   Filler Burst Type....... " << get_value_string(filler_names, trx->cfg.filler) << std::endl;
	ost << "   Filler Burst TSC........ " << trx->cfg.rtsc << std::endl;
	ost << "   Filler Burst RACH Delay. " << trx->cfg.rach_delay << std::endl;
	ost << "   Multi-Carrier........... " << trx->cfg.multi_arfcn << std::endl;
	ost << "   LO freq. offset......... " << trx->cfg.offset << std::endl;
	if (trx->cfg.freq_offset_khz != 0)
		ost << "   Tune freq. offset....... " << trx->cfg.freq_offset_khz << std::endl;
	ost << "   RSSI to dBm offset...... " << trx->cfg.rssi_offset << (trx->cfg.force_rssi_offset ? "" : " (relative)") << std::endl;
	ost << "   Swap channels........... " << trx->cfg.swap_channels << std::endl;
	ost << "   Tx Antennas.............";
	for (i = 0; i < trx->cfg.num_chans; i++) {
		std::string p = charp2str(trx->cfg.chans[i].tx_path);
		ost << " '" << ((p != "") ? p : "<default>") <<  "'";
	}
	ost << std::endl;
	ost << "   Rx Antennas.............";
	for (i = 0; i < trx->cfg.num_chans; i++) {
		std::string p = charp2str(trx->cfg.chans[i].rx_path);
		ost << " '" << ((p != "") ? p : "<default>") <<  "'";
	}
	ost << std::endl;

	LOG(INFO) << ost << std::endl;
}

static void trx_stop()
{
	LOG(NOTICE) << "Shutting down transceiver..." << std::endl;

	delete transceiver;
	delete radio;
	delete usrp;
}

static int trx_start(struct trx_ctx *trx)
{
	int type, chans;
	RadioDevice::InterfaceType iface = RadioDevice::NORMAL;

	/* Create the low level device object */
	if (trx->cfg.multi_arfcn)
		iface = RadioDevice::MULTI_ARFCN;

	usrp = RadioDevice::make(iface, &trx->cfg);
	type = usrp->open();
	if (type < 0) {
		LOG(ALERT) << "Failed to create radio device" << std::endl;
		goto shutdown;
	}

	/* Setup the appropriate device interface */
	radio = makeRadioInterface(trx, usrp, type);
	if (!radio)
		goto shutdown;

	/* Create the transceiver core */
	if (makeTransceiver(trx, radio) < 0)
		goto shutdown;

	chans = transceiver->numChans();
	LOG(NOTICE) << "-- Transceiver active with "
		  << chans << " channel(s)" << std::endl;

	return 0;

shutdown:
	trx_stop();
	return -1;
}

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

	tall_trx_ctx = talloc_named_const(NULL, 0, "OsmoTRX");
	msgb_talloc_ctx_init(tall_trx_ctx, 0);
	g_vty_info.tall_ctx = tall_trx_ctx;

	setup_signal_handlers();

	g_trx_ctx = vty_trx_ctx_alloc(tall_trx_ctx);

	convolve_init();
	convert_init();

	osmo_init_logging2(tall_trx_ctx, &log_info);
	log_enable_multithread();
	osmo_stats_init(tall_trx_ctx);
	vty_init(&g_vty_info);
	logging_vty_add_cmds();
	ctrl_vty_init(tall_trx_ctx);
	osmo_cpu_sched_vty_init(tall_trx_ctx);
	trx_vty_init(g_trx_ctx);

	osmo_talloc_vty_add_cmds();
	osmo_stats_vty_add_cmds();

	handle_options(argc, argv, g_trx_ctx);

	rate_ctr_init(tall_trx_ctx);

	rc = vty_read_config_file(config_file, NULL);
	if (rc < 0) {
		fprintf(stderr, "Failed to open config file: '%s'\n", config_file);
		exit(2);
	}

	rc = telnet_init_default(tall_trx_ctx, NULL, OSMO_VTY_PORT_TRX);
	if (rc < 0)
		exit(1);

	g_ctrlh = ctrl_interface_setup(NULL, OSMO_CTRL_PORT_TRX, NULL);
	if (!g_ctrlh) {
		LOG(ERROR) << "Failed to create CTRL interface.\n";
		exit(1);
	}

	/* Backward compatibility: Hack to have 1 channel allocated by default.
	 * Can be Dropped once we * get rid of "-c" cmdline param */
	if (g_trx_ctx->cfg.num_chans == 0) {
		g_trx_ctx->cfg.num_chans = 1;
		g_trx_ctx->cfg.chans[0].trx = g_trx_ctx;
		g_trx_ctx->cfg.chans[0].idx = 0;
		LOG(ERROR) << "No explicit channel config found. Make sure you" \
			" configure channels in VTY config. Using 1 channel as default," \
			" but expect your config to break in the future.";
	}

	print_simd_info();
	print_config(g_trx_ctx);

	if (trx_validate_config(g_trx_ctx) < 0) {
		LOG(ERROR) << "Config failure - exiting";
		return EXIT_FAILURE;
	}

	if (g_trx_ctx->cfg.sched_rr) {
		if (set_sched_rr(g_trx_ctx->cfg.sched_rr) < 0)
			return EXIT_FAILURE;
	}

	osmo_signal_register_handler(SS_MAIN, transc_sig_cb, NULL);
	trx_rate_ctr_init(tall_trx_ctx, g_trx_ctx);

	srandom(time(NULL));

	if(trx_start(g_trx_ctx) < 0)
		return EXIT_FAILURE;

	while (!gshutdown)
		osmo_select_main(0);

	trx_stop();

	osmo_fd_unregister(&signal_ofd);
	osmo_fd_close(&signal_ofd);
	osmo_signal_unregister_handler(SS_MAIN, transc_sig_cb, NULL);
	return 0;
}
