/* Bloated main routine, refactor */
/*
 * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2010-2011 by On-Waves
 * All Rights Reserved
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <mtp_data.h>
#include <msc_connection.h>
#include <mtp_level3.h>
#include <thread.h>
#include <bss_patch.h>
#include <bssap_sccp.h>
#include <bsc_data.h>
#include <cellmgr_debug.h>
#include <bsc_sccp.h>
#include <ss7_application.h>

#include <osmocore/talloc.h>

#include <osmocom/vty/vty.h>
#include <osmocom/vty/telnet_interface.h>

#include <sys/stat.h>
#include <sys/types.h>

#include <signal.h>

static struct log_target *stderr_target;

char *config = "cellmgr_ng.cfg";

struct bsc_data *bsc;
extern void cell_vty_init(void);
extern void handle_options(int argc, char **argv);

static void sigint()
{
	static pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;
	static int handled = 0;

	struct mtp_link_set *set;

	/* failed to lock */
	if (pthread_mutex_trylock(&exit_mutex) != 0)
		return;
	if (handled)
		goto out;

	printf("Terminating.\n");
	handled = 1;
	if (bsc) {
		llist_for_each_entry(set, &bsc->linksets, entry)
			link_shutdown_all(set);
	}

	exit(0);

out:
	pthread_mutex_unlock(&exit_mutex);
}

static void sigusr2()
{
	struct msc_connection *msc;
	printf("Closing the MSC connection on demand.\n");

	llist_for_each_entry(msc, &bsc->mscs, entry)
		msc_close_connection(msc);
}

static void bsc_msc_forward_init(struct msc_connection *msc)
{
	msc->ip = talloc_strdup(msc, "127.0.0.1");
	msc->ping_time = 20;
	msc->pong_time = 5;
	msc->msc_time = 20;
}

int main(int argc, char **argv)
{
	int rc;
	struct msc_connection *msc;
	struct mtp_link_set *set;
	struct ss7_application *app;

	thread_init();

	log_init(&log_info);
	stderr_target = log_target_create_stderr();
	log_add_target(stderr_target);

	/* enable filters */
	log_set_all_filter(stderr_target, 1);
	log_set_category_filter(stderr_target, DINP, 1, LOGL_INFO);
	log_set_category_filter(stderr_target, DSCCP, 1, LOGL_INFO);
	log_set_category_filter(stderr_target, DMSC, 1, LOGL_INFO);
	log_set_category_filter(stderr_target, DMGCP, 1, LOGL_INFO);
	log_set_print_timestamp(stderr_target, 1);
	log_set_use_color(stderr_target, 0);

	sccp_set_log_area(DSCCP);

	bsc = bsc_data_create();
	if (!bsc)
		return -1;

	/* msc data */
	msc = msc_connection_create(bsc, 1);
	if (!msc) {
		LOGP(DINP, LOGL_ERROR, "Failed to create the MSC connection.\n");
		return -1;
	}
	bsc_msc_forward_init(msc);

	handle_options(argc, argv);

	signal(SIGPIPE, SIG_IGN);
	signal(SIGINT, sigint);
	signal(SIGUSR2, sigusr2);
	srand(time(NULL));

	cell_vty_init();
	if (vty_read_config_file(config, NULL) < 0) {
		fprintf(stderr, "Failed to read the VTY config.\n");
		return -1;
	}

	rc = telnet_init(NULL, NULL, 4242);
	if (rc < 0)
		return rc;

	set = link_init(bsc);
	if (!set)
		return -1;

	app = ss7_application_alloc(bsc);
	if (!app) {
		LOGP(DINP, LOGL_ERROR, "Failed to create the SS7 application.\n");
		return -1;
	}

	ss7_application_setup(app, APP_CELLMGR,
			      SS7_SET_LINKSET, 0,
			      SS7_SET_MSC, 0);
	ss7_application_start(app);

        while (1) {
		bsc_select_main(0);
        }

	return 0;
}

