/* (C) 2015 by sysmocom s.f.m.c. GmbH
 * All Rights Reserved
 *
 * Author: Neels Hofmeyr
 *
 * 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 <string.h>

#include <ares.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <osmocom/core/talloc.h>
#include <osmocom/vty/command.h>
#include <osmocom/vty/misc.h>

#include <openbsc/vty.h>
#include <openbsc/gtphub.h>

/* TODO split GRX ares from sgsn into a separate struct and allow use without
 * globals. */
#include <openbsc/sgsn.h>
extern struct sgsn_instance *sgsn;

static struct gtphub *g_hub = 0;
static struct gtphub_cfg *g_cfg = 0;

static struct cmd_node gtphub_node = {
	GTPHUB_NODE,
	"%s(config-gtphub)# ",
	1,
};

#define GTPH_DEFAULT_CONTROL_PORT 2123
#define GTPH_DEFAULT_USER_PORT 2152

static void write_addrs(struct vty *vty, const char *name,
			struct gtphub_cfg_addr *c, struct gtphub_cfg_addr *u)
{
	if ((c->port == GTPH_DEFAULT_CONTROL_PORT)
	    && (u->port == GTPH_DEFAULT_USER_PORT)
	    && (strcmp(c->addr_str, u->addr_str) == 0)) {
		/* Default port numbers and same IP address: write "short"
		 * variant. */
		vty_out(vty, " %s %s%s",
			name,
			c->addr_str,
			VTY_NEWLINE);
		return;
	}

	vty_out(vty, " %s ctrl %s %d user %s %d%s",
		name,
		c->addr_str, (int)c->port,
		u->addr_str, (int)u->port,
		VTY_NEWLINE);

	struct ares_addr_node *server;
	for (server = sgsn->ares_servers; server; server = server->next)
		vty_out(vty, " grx-dns-add %s%s", inet_ntoa(server->addr.addr4), VTY_NEWLINE);
}

static int config_write_gtphub(struct vty *vty)
{
	vty_out(vty, "gtphub%s", VTY_NEWLINE);

	write_addrs(vty, "bind-to-sgsns",
		    &g_cfg->to_sgsns[GTPH_PLANE_CTRL].bind,
		    &g_cfg->to_sgsns[GTPH_PLANE_USER].bind);

	write_addrs(vty, "bind-to-ggsns",
		    &g_cfg->to_ggsns[GTPH_PLANE_CTRL].bind,
		    &g_cfg->to_ggsns[GTPH_PLANE_USER].bind);

	if (g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].addr_str) {
		write_addrs(vty, "ggsn-proxy",
			    &g_cfg->ggsn_proxy[GTPH_PLANE_CTRL],
			    &g_cfg->ggsn_proxy[GTPH_PLANE_USER]);
	}

	return CMD_SUCCESS;
}

DEFUN(cfg_gtphub, cfg_gtphub_cmd,
      "gtphub",
      "Configure the GTP hub")
{
	vty->node = GTPHUB_NODE;
	return CMD_SUCCESS;
}

#define BIND_ARGS  "ctrl ADDR <0-65535> user ADDR <0-65535>"
#define BIND_DOCS  \
	"Set GTP-C bind\n" \
	"GTP-C local IP address (v4 or v6)\n" \
	"GTP-C local port\n" \
	"Set GTP-U bind\n" \
	"GTP-U local IP address (v4 or v6)\n" \
	"GTP-U local port\n"


DEFUN(cfg_gtphub_bind_to_sgsns_short, cfg_gtphub_bind_to_sgsns_short_cmd,
	"bind-to-sgsns ADDR",
	"GTP Hub Parameters\n"
	"Set the local bind address to listen for SGSNs, for both GTP-C and GTP-U\n"
	"Local IP address (v4 or v6)\n"
	)
{
	int i;
	for (i = 0; i < GTPH_PLANE_N; i++)
		g_cfg->to_sgsns[i].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
	g_cfg->to_sgsns[GTPH_PLANE_CTRL].bind.port = GTPH_DEFAULT_CONTROL_PORT;
	g_cfg->to_sgsns[GTPH_PLANE_USER].bind.port = GTPH_DEFAULT_USER_PORT;
	return CMD_SUCCESS;
}

DEFUN(cfg_gtphub_bind_to_ggsns_short, cfg_gtphub_bind_to_ggsns_short_cmd,
	"bind-to-ggsns ADDR",
	"GTP Hub Parameters\n"
	"Set the local bind address to listen for GGSNs, for both GTP-C and GTP-U\n"
	"Local IP address (v4 or v6)\n"
	)
{
	int i;
	for (i = 0; i < GTPH_PLANE_N; i++)
		g_cfg->to_ggsns[i].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
	g_cfg->to_ggsns[GTPH_PLANE_CTRL].bind.port = GTPH_DEFAULT_CONTROL_PORT;
	g_cfg->to_ggsns[GTPH_PLANE_USER].bind.port = GTPH_DEFAULT_USER_PORT;
	return CMD_SUCCESS;
}


static int handle_binds(struct gtphub_cfg_bind *b, const char **argv)
{
	b[GTPH_PLANE_CTRL].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
	b[GTPH_PLANE_CTRL].bind.port = atoi(argv[1]);
	b[GTPH_PLANE_USER].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[2]);
	b[GTPH_PLANE_USER].bind.port = atoi(argv[3]);
	return CMD_SUCCESS;
}

DEFUN(cfg_gtphub_bind_to_sgsns, cfg_gtphub_bind_to_sgsns_cmd,
	"bind-to-sgsns " BIND_ARGS,
	"GTP Hub Parameters\n"
	"Set the local bind addresses and ports to listen for SGSNs\n"
	BIND_DOCS
	)
{
	return handle_binds(g_cfg->to_sgsns, argv);
}

DEFUN(cfg_gtphub_bind_to_ggsns, cfg_gtphub_bind_to_ggsns_cmd,
	"bind-to-ggsns " BIND_ARGS,
	"GTP Hub Parameters\n"
	"Set the local bind addresses and ports to listen for GGSNs\n"
	BIND_DOCS
	)
{
	return handle_binds(g_cfg->to_ggsns, argv);
}

DEFUN(cfg_gtphub_ggsn_proxy_short, cfg_gtphub_ggsn_proxy_short_cmd,
	"ggsn-proxy ADDR",
	"GTP Hub Parameters\n"
	"Redirect all GGSN bound traffic to default ports on this address (another gtphub)\n"
	"Remote IP address (v4 or v6)\n"
	)
{
	g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
	g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].port = GTPH_DEFAULT_CONTROL_PORT;
	g_cfg->ggsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
	g_cfg->ggsn_proxy[GTPH_PLANE_USER].port = GTPH_DEFAULT_USER_PORT;
	return CMD_SUCCESS;
}

DEFUN(cfg_gtphub_ggsn_proxy, cfg_gtphub_ggsn_proxy_cmd,
	"ggsn-proxy " BIND_ARGS,
	"GTP Hub Parameters\n"
	"Redirect all GGSN bound traffic to these addresses and ports (another gtphub)\n"
	BIND_DOCS
	)
{
	g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
	g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].port = atoi(argv[1]);
	g_cfg->ggsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[2]);
	g_cfg->ggsn_proxy[GTPH_PLANE_USER].port = atoi(argv[3]);
	return CMD_SUCCESS;
}

DEFUN(cfg_gtphub_sgsn_proxy_short, cfg_gtphub_sgsn_proxy_short_cmd,
	"sgsn-proxy ADDR",
	"GTP Hub Parameters\n"
	"Redirect all SGSN bound traffic to default ports on this address (another gtphub)\n"
	"Remote IP address (v4 or v6)\n"
	)
{
	g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
	g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].port = GTPH_DEFAULT_CONTROL_PORT;
	g_cfg->sgsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
	g_cfg->sgsn_proxy[GTPH_PLANE_USER].port = GTPH_DEFAULT_USER_PORT;
	return CMD_SUCCESS;
}

DEFUN(cfg_gtphub_sgsn_proxy, cfg_gtphub_sgsn_proxy_cmd,
	"sgsn-proxy " BIND_ARGS,
	"GTP Hub Parameters\n"
	"Redirect all SGSN bound traffic to these addresses and ports (another gtphub)\n"
	BIND_DOCS
	)
{
	g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]);
	g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].port = atoi(argv[1]);
	g_cfg->sgsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[2]);
	g_cfg->sgsn_proxy[GTPH_PLANE_USER].port = atoi(argv[3]);
	return CMD_SUCCESS;
}


/* Copied from sgsn_vty.h */
DEFUN(cfg_grx_ggsn, cfg_grx_ggsn_cmd,
	"grx-dns-add A.B.C.D",
	"Add DNS server\nIPv4 address\n")
{
	struct ares_addr_node *node = talloc_zero(tall_bsc_ctx, struct ares_addr_node);
	node->family = AF_INET;
	inet_aton(argv[0], &node->addr.addr4);

	node->next = sgsn->ares_servers;
	sgsn->ares_servers = node;
	return CMD_SUCCESS;
}


/*
(show gtphub all, show gtphub stats, show gtphub teidmap,
 show gtphub peers, ...)
*/

static void show_bind_stats_all(struct vty *vty)
{
	int plane_idx;
	for (plane_idx = 0; plane_idx < GTPH_PLANE_N; plane_idx++) {
		vty_out(vty, "- %s Plane:%s",
			gtphub_plane_idx_names[plane_idx], VTY_NEWLINE);

		struct gtphub_bind *b = &g_hub->to_ggsns[plane_idx];
		vty_out(vty, "  - to/from GGSNs: %s port %d%s",
			gsn_addr_to_str(&b->local_addr), (int)b->local_port,
			VTY_NEWLINE);
		vty_out_rate_ctr_group(vty, "    ", b->counters_io);

		b = &g_hub->to_sgsns[plane_idx];
		vty_out(vty, "  - to/from SGSNs: %s port %d%s",
			gsn_addr_to_str(&b->local_addr), (int)b->local_port,
			VTY_NEWLINE);
		vty_out_rate_ctr_group(vty, "    ", b->counters_io);
	}
}

/*
static void show_peers_summary(struct vty *vty)
{
	int c
	int plane_idx;
}
*/

static void show_tei_maps_summary(struct vty *vty)
{
	time_t now = gtphub_now();

	unsigned long long int count_all = 0; /* ...just joking. */

	const int w = 36;
	int max_expiry = g_hub->expire_tei_maps.expiry_in_seconds;
	float seconds_per_step = ((float)max_expiry) / w;

	/* Print TEI mapping expiry in an ASCII histogram, like:
	     TEI map summary
	       Legend:  '_'=0  '.'<=1%  ':'<=2%  '|'<=10%  '#'>10%  (10.0 m/step)
	       CTRL: 30 mappings, valid for 360m[#__:.____|___.____:__.______________]1m
	       USER: 30 mappings, valid for 360m[#__:.____|___.____:__.______________]1m
	       4 TEI mappings in total, last expiry in 359.4 min
	 */
	vty_out(vty,
		"TEI map summary%s"
		"  Legend:  '_'=0  '.'<=1%%  ':'<=2%%  '|'<=10%%  '#'>10%%  (%.1f m/step)%s",
		VTY_NEWLINE,
		seconds_per_step / 60.,
		VTY_NEWLINE);

	int last_expiry = 0;
	int plane_idx;
	for (plane_idx = 0; plane_idx < GTPH_PLANE_N; plane_idx++) {

		unsigned int count = 0;

		int histogram[w];
		memset(histogram, 0, sizeof(histogram));

		struct nr_mapping *m;
		llist_for_each_entry(m, &g_hub->tei_map[plane_idx].mappings, entry) {
			count ++;
			int expiry = m->expiry_entry.expiry - now;
			last_expiry = (last_expiry > expiry) ? last_expiry : expiry;

			int hi = ((float)expiry) / seconds_per_step;
			if (hi < 0)
				hi = 0;
			if (hi > (w - 1))
				hi = w - 1;
			histogram[hi] ++;
		}

		vty_out(vty,
			"  %4s: %u mappings, valid for %dm[",
			gtphub_plane_idx_names[plane_idx],
			count, max_expiry / 60);

		int i;
		for (i = w - 1; i >= 0; i--) {
			char c;
			int val = histogram[i];
			int percent = 100. * val / count;
			if (!val)
				c = '_';
			else if (percent <= 1)
				c = '.';
			else if (percent <= 2)
				c = ':';
			else if (percent <= 10)
				c = '|';
			else c = '#';
			vty_out(vty, "%c", c);
		}
		vty_out(vty, "]1m%s", VTY_NEWLINE);

		count_all += count;
	}
	vty_out(vty, "  %llu TEI mappings in total, last expiry in %.1f min%s",
		count_all,
		((float)last_expiry) / 60.,
		VTY_NEWLINE);
}

static void show_tei_maps_all(struct vty *vty)
{
	time_t now = gtphub_now();

	unsigned long long int count_all = 0; /* ...just joking. */

	vty_out(vty, "All TEI mappings:%s", VTY_NEWLINE);
	int plane_idx;
	for (plane_idx = 0; plane_idx < GTPH_PLANE_N; plane_idx++) {
		vty_out(vty,
			"- %s Plane:%s"
			"  (timeout) replaced-TEI <--> original-TEI from-peer%s",
			gtphub_plane_idx_names[plane_idx],
			VTY_NEWLINE, VTY_NEWLINE);

		unsigned int count = 0;
		struct nr_mapping *m;
		llist_for_each_entry(m, &g_hub->tei_map[plane_idx].mappings, entry) {
			struct gtphub_peer_port *pp = m->origin;
			vty_out(vty,
				"  (%4dm) %8x <--> %8x %s",
				-(int)((m->expiry_entry.expiry - now) / 60),
				(uint32_t)m->repl,
				(uint32_t)m->orig,
				gsn_addr_to_str(&pp->peer_addr->addr));
			if (pp->port != gtphub_plane_idx_default_port[plane_idx])
				vty_out(vty, " port %d", (int)pp->port);
			vty_out(vty, VTY_NEWLINE);
			count ++;
		}
		vty_out(vty, "  (%u %s TEI mappings)%s", count,
			gtphub_plane_idx_names[plane_idx], VTY_NEWLINE);
		count_all += count;
	}
	vty_out(vty, "- %llu TEI mappings in total%s", count_all, VTY_NEWLINE);
}

DEFUN(show_gtphub_tei_summary, show_gtphub_tei_summary_cmd, "show gtphub tei summary",
      SHOW_STR "TEI mappings summary")
{
	show_tei_maps_summary(vty);
	return CMD_SUCCESS;
}

DEFUN(show_gtphub_tei_dump, show_gtphub_tei_dump_cmd, "show gtphub tei dump",
      SHOW_STR "Dump all current TEI mappings")
{
	show_tei_maps_all(vty);
	return CMD_SUCCESS;
}

DEFUN(show_gtphub, show_gtphub_cmd, "show gtphub all",
      SHOW_STR "Display information about the GTP hub")
{
	show_bind_stats_all(vty);
	show_tei_maps_summary(vty);
	return CMD_SUCCESS;
}


int gtphub_vty_init(struct gtphub *global_hub, struct gtphub_cfg *global_cfg)
{
	g_hub = global_hub;
	g_cfg = global_cfg;

	install_element_ve(&show_gtphub_cmd);
	install_element_ve(&show_gtphub_tei_summary_cmd);
	install_element_ve(&show_gtphub_tei_dump_cmd);

	install_element(CONFIG_NODE, &cfg_gtphub_cmd);
	install_node(&gtphub_node, config_write_gtphub);
	vty_install_default(GTPHUB_NODE);

	install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_sgsns_short_cmd);
	install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_sgsns_cmd);
	install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_ggsns_short_cmd);
	install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_ggsns_cmd);
	install_element(GTPHUB_NODE, &cfg_gtphub_ggsn_proxy_short_cmd);
	install_element(GTPHUB_NODE, &cfg_gtphub_ggsn_proxy_cmd);
	install_element(GTPHUB_NODE, &cfg_gtphub_sgsn_proxy_short_cmd);
	install_element(GTPHUB_NODE, &cfg_gtphub_sgsn_proxy_cmd);
	install_element(GTPHUB_NODE, &cfg_grx_ggsn_cmd);

	return 0;
}

int gtphub_cfg_read(struct gtphub_cfg *cfg, const char *config_file)
{
	int rc;

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

	return 0;
}
