/* Simple Osmocom System Monitor (osysmon) */

/* (C) 2018 by Harald Welte <laforge@gnumonks.org>
 * All Rights Reserved.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *  MA  02110-1301, USA.
 */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <getopt.h>

#include "config.h"
#include "osysmon.h"
#include "value_node.h"

#include <osmocom/core/msgb.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/application.h>

static struct log_info log_info = {};

static int osysmon_go_parent(struct vty *vty)
{
	switch (vty->node) {
	case CTRL_CLIENT_NODE:
	case CTRL_CLIENT_GETVAR_NODE:
		return osysmon_ctrl_go_parent(vty);
	}
	return vty->node;
}

static int osysmon_is_config_node(struct vty *vty, int node)
{
	switch (node) {
	/* no non-config-nodes */
	default:
		return 1;
	}
}


static struct vty_app_info vty_info = {
	.name = "osysmon",
	.copyright =
	"Copyright (C) 2008-2018 Harald Welte\r\n"
	"License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>\r\n"
	"This is free software: you are free to change and redistribute it.\r\n"
	"There is NO WARRANTY, to the extent permitted by law.\r\n",
	.version = PACKAGE_VERSION,
	.go_parent_cb = osysmon_go_parent,
	.is_config_node = osysmon_is_config_node,
};

struct osysmon_state *g_oss;


static void print_node(struct value_node *node, unsigned int indent)
{
	unsigned int i;

	if (node->value) {
		for (i = 0; i < indent; i++)
			fputc(' ', stdout);
		printf("%s: %s\n", node->name, node->value);
	} else {
		struct value_node *vn;
		for (i = 0; i < indent; i++)
			fputc(' ', stdout);
		printf("%s\n", node->name);
		llist_for_each_entry(vn, &node->children, list)
			print_node(vn, indent+2);
	}
}

static void display_update(struct value_node *root)
{
	print_node(root, 0);
}

static void signal_handler(int signal)
{
	fprintf(stderr, "Signal %u received", signal);

	switch(signal) {
	case SIGUSR1:
		talloc_report(g_oss, stderr);
		break;
	default:
		break;
	}
}

static void print_usage()
{
	printf("Usage: osmo-sysmon\n");
}

static void print_help()
{
	printf("  -h --help                  This text.\n");
	printf("  -c --config-file filename  The config file to use.\n");
	printf("  -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM  Enable debugging.\n");
	printf("  -D --daemonize             Fork the process into a background daemon.\n");
	printf("  -s --disable-color         Do not print ANSI colors in the log\n");
	printf("  -T --timestamp             Prefix every log line with a timestamp.\n");
	printf("  -e --log-level number      Set a global loglevel.\n");
	printf("  -V --version               Print the version of osmo-sysmon.\n");
}

static struct {
	const char *config_file;
	bool daemonize;
} cmdline_opts = {
	.config_file = "osmo-sysmon.cfg",
	.daemonize = false,
};

static void handle_options(int argc, char **argv)
{
	while (1) {
		int option_index = 0, c;
		static struct option long_options[] = {
			{"help", 0, 0, 'h'},
			{"config-file", 1, 0, 'c'},
			{"debug", 1, 0, 'd'},
			{"daemonize", 0, 0, 'D'},
			{"disable-color", 0, 0, 's'},
			{"log-level", 1, 0, 'e'},
			{"timestamp", 0, 0, 'T'},
			{"version", 0, 0, 'V' },
			{0, 0, 0, 0}
		};

		c = getopt_long(argc, argv, "hc:d:Dse:TV",
				long_options, &option_index);
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			print_usage();
			print_help();
			exit(0);
		case 'c':
			cmdline_opts.config_file = optarg;
			break;
		case 'd':
			log_parse_category_mask(osmo_stderr_target, optarg);
			break;
		case 'D':
			cmdline_opts.daemonize = 1;
			break;
		case 's':
			log_set_use_color(osmo_stderr_target, 0);
			break;
		case 'e':
			log_set_log_level(osmo_stderr_target, atoi(optarg));
			break;
		case 'T':
			log_set_print_timestamp(osmo_stderr_target, 1);
			break;
		case 'V':
			print_version(1);
			exit(0);
			break;
		default:
			/* catch unknown options *as well as* missing arguments. */
			fprintf(stderr, "Error in command line options. Exiting.\n");
			exit(-1);
			break;
		}
	}
}

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

	osmo_init_logging2(NULL, &log_info);

	g_oss = talloc_zero(NULL, struct osysmon_state);
	INIT_LLIST_HEAD(&g_oss->ctrl_clients);
	INIT_LLIST_HEAD(&g_oss->openvpn_clients);
	INIT_LLIST_HEAD(&g_oss->netdevs);
	INIT_LLIST_HEAD(&g_oss->files);

	vty_init(&vty_info);
	handle_options(argc, argv);
	osysmon_sysinfo_init();
	osysmon_ctrl_init();
	osysmon_openvpn_init();
	osysmon_rtnl_init();
	ping_init = osysmon_ping_init();
	osysmon_file_init();

	signal(SIGUSR1, &signal_handler);
	signal(SIGUSR2, &signal_handler);
	osmo_init_ignore_signals();

	rc = vty_read_config_file(cmdline_opts.config_file, NULL);
	if (rc < 0) {
		fprintf(stderr, "Failed to parse the config file %s\n",
			cmdline_opts.config_file);
		exit(2);
	}

	if (cmdline_opts.daemonize) {
		rc = osmo_daemonize();
		if (rc < 0) {
			perror("Error during daemonize");
			exit(1);
		}
	}

	while (1) {
		struct value_node *root = value_node_add(NULL, "root", NULL);
		int vpns = osysmon_openvpn_poll(root);
		osysmon_sysinfo_poll(root);
		osysmon_ctrl_poll(root);
		osysmon_rtnl_poll(root);

		if (ping_init == 0)
			osysmon_ping_poll(root);

		osysmon_file_poll(root);

		display_update(root);
		value_node_del(root);

		if (vpns)
			osmo_select_main(0);

		sleep(1);
	}

	exit(0);
}
