/*
 *   teamnl.c - Team device Netlink tool
 *   Copyright (C) 2012-2015 Jiri Pirko <jiri@resnulli.us>
 *
 *   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.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
#include <sys/signalfd.h>
#include <signal.h>
#include <unistd.h>
#include <team.h>

#include <private/misc.h>

#define CMD_PARAM_MAX_CNT 8

struct cmd_ctx {
	int argc;
	char **argv;
	char *port_devname_arg;
	char *array_index_arg;
	bool port_ifindex_present;
	uint32_t port_ifindex;
	bool array_index_present;
	uint32_t array_index;
};

typedef int (*run_cmd_t)(char *cmd_name, struct team_handle *th,
			 struct cmd_ctx *cmd_ctx);

struct cmd_type {
	char *name;
	char *params[CMD_PARAM_MAX_CNT];
	run_cmd_t run_cmd;
};

static int run_cmd_ports(char *cmd_name, struct team_handle *th,
			 struct cmd_ctx *cmd_ctx)
{
	struct team_port *port;
	char buf[120];
	bool trunc;

	team_for_each_port(port, th) {
		trunc = team_port_str(port, buf, sizeof(buf));
		printf("%s %s\n", buf, trunc ? "<trunc>" : "");
	}
	return 0;
}

static int run_cmd_options(char *cmd_name, struct team_handle *th,
			   struct cmd_ctx *cmd_ctx)
{
	struct team_option *option;
	char buf[120];
	bool trunc;

	team_for_each_option(option, th) {
		trunc = team_option_str(th, option, buf, sizeof(buf));
		printf("%s %s\n", buf, trunc ? "<trunc>" : "");
	}
	return 0;
}

static struct team_option *__find_option(struct team_handle *th, char *opt_name,
					 struct cmd_ctx *cmd_ctx)
{
	if (cmd_ctx->array_index_present && cmd_ctx->port_ifindex_present)
		return team_get_option(th, "npa", opt_name,
				       cmd_ctx->port_ifindex,
				       cmd_ctx->array_index);
	else if (cmd_ctx->array_index_present)
		return team_get_option(th, "na", opt_name,
				       cmd_ctx->array_index);
	else if (cmd_ctx->port_ifindex_present)
		return team_get_option(th, "np", opt_name,
				       cmd_ctx->port_ifindex);
	else
		return team_get_option(th, "n", opt_name);
}

#define BUFSIZSTEP 1024

static int run_cmd_getoption(char *cmd_name, struct team_handle *th,
			     struct cmd_ctx *cmd_ctx)
{
	struct team_option *option;
	char *buf = NULL;
	char *tmpbuf;
	size_t bufsiz = 0;
	bool trunc;

	if (cmd_ctx->argc < 1) {
		fprintf(stderr, "%s: Option name as a command line parameter expected.\n",
			cmd_name);
		return -EINVAL;
	}
	option = __find_option(th, cmd_ctx->argv[0], cmd_ctx);
	if (!option)
		return -ENOENT;

	do {
		bufsiz += BUFSIZSTEP;
		tmpbuf = realloc(buf, bufsiz);
		if (!tmpbuf) {
			free(buf);
			return -ENOMEM;
		}
		buf = tmpbuf;
		trunc = team_option_value_str(option, buf, bufsiz);
	} while(trunc);

	printf("%s\n", buf);
	free(buf);
	return 0;
}

static int run_cmd_setoption(char *cmd_name, struct team_handle *th,
			     struct cmd_ctx *cmd_ctx)
{
	struct team_option *option;

	if (cmd_ctx->argc < 1) {
		fprintf(stderr, "%s: Option name as a command line parameter expected.\n",
			cmd_name);
		return -EINVAL;
	}
	if (cmd_ctx->argc < 2) {
		fprintf(stderr, "%s: Option value as a command line parameter expected.\n",
			cmd_name);
		return -EINVAL;
	}
	option = __find_option(th, cmd_ctx->argv[0], cmd_ctx);
	if (!option)
		return -ENOENT;

	return team_set_option_value_from_string(th, option, cmd_ctx->argv[1]);
}

static int run_main_loop(struct team_handle *th)
{
	fd_set rfds;
	fd_set rfds_tmp;
	int fdmax;
	int ret;
	sigset_t mask;
	int sfd;
	int tfd;
	int err = 0;

	sigemptyset(&mask);
	sigaddset(&mask, SIGINT);
	sigaddset(&mask, SIGQUIT);

	ret = sigprocmask(SIG_BLOCK, &mask, NULL);
	if (ret == -1) {
		fprintf(stderr, "Failed to set blocked signals\n");
		return -errno;
	}

	sfd = signalfd(-1, &mask, 0);
	if (sfd == -1) {
		fprintf(stderr, "Failed to open signalfd\n");
		return -errno;
	}

	FD_ZERO(&rfds);
	FD_SET(sfd, &rfds);
	fdmax = sfd;

	tfd = team_get_event_fd(th);
	FD_SET(tfd, &rfds);
	if (tfd > fdmax)
		fdmax = tfd;

	fdmax++;

	for (;;) {
		rfds_tmp = rfds;
		ret = select(fdmax, &rfds_tmp, NULL, NULL, NULL);
		if (ret == -1) {
			fprintf(stderr, "Select failed\n");
			err = -errno;
			goto out;
		}
		if (FD_ISSET(sfd, &rfds_tmp)) {
			struct signalfd_siginfo fdsi;
			ssize_t len;

			len = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
		        if (len != sizeof(struct signalfd_siginfo)) {
				fprintf(stderr, "Unexpected data length came from signalfd\n");
				err = -EINVAL;
				goto out;
			}
			switch (fdsi.ssi_signo) {
			case SIGINT:
			case SIGQUIT:
			case SIGTERM:
				goto out;
			default:
				fprintf(stderr, "Read unexpected signal\n");
				err = -EINVAL;
				goto out;
			}

		}
		if (FD_ISSET(tfd, &rfds_tmp)) {
			err = team_handle_events(th);
			if (err) {
				fprintf(stderr, "Team handle events failed\n");
				return err;
			}
		}
	}
out:
	close(sfd);
	return err;
}

enum {
	MONITOR_STYLE_CHANGED,
	MONITOR_STYLE_ALL,
};

struct monitor_priv {
	unsigned int style;
};

static bool __should_show(struct monitor_priv *mpriv, bool changed)
{
	if (mpriv->style == MONITOR_STYLE_ALL)
		return true;
	if (mpriv->style == MONITOR_STYLE_CHANGED && changed)
		return true;
	return false;
}

static void monitor_port_list(struct team_handle *th,
			      struct monitor_priv *mpriv)
{
	struct team_port *port;
	char buf[120];
	bool trunc;
	bool skip = true;

	team_for_each_port(port, th) {
		if (__should_show(mpriv, team_is_port_changed(port))) {
			skip = false;
			break;
		}
	}
	if (skip)
		return;

	printf("ports:\n");
	team_for_each_port(port, th) {
		if (!__should_show(mpriv, team_is_port_changed(port)))
			continue;
		trunc = team_port_str(port, buf, sizeof(buf));
		printf("  %s %s\n", buf, trunc ? "..." : "");
	}
}

static void monitor_option_list(struct team_handle *th,
				struct monitor_priv *mpriv)
{
	struct team_option *option;
	char buf[120];
	bool trunc;
	bool skip = true;

	team_for_each_option(option, th) {
		if (__should_show(mpriv, team_is_option_changed(option))) {
			skip = false;
			break;
		}
	}
	if (skip)
		return;

	printf("options:\n");
	team_for_each_option(option, th) {
		if (!__should_show(mpriv, team_is_option_changed(option)))
			continue;
		trunc = team_option_str(th, option, buf, sizeof(buf));
		printf("  %s%s%s\n", buf, trunc ? "..." : "",
		       team_is_option_changed(option) ? " changed" : "");
	}
}

static void monitor_ifinfo_list(struct team_handle *th,
				struct monitor_priv *mpriv)
{
	struct team_ifinfo *ifinfo;
	char buf[120];
	bool trunc;
	bool skip = true;

	team_for_each_ifinfo(ifinfo, th) {
		if (__should_show(mpriv, team_is_ifinfo_changed(ifinfo))) {
			skip = false;
			break;
		}
	}
	if (skip)
		return;

	printf("ifinfos:\n");
	team_for_each_ifinfo(ifinfo, th) {
		if (!__should_show(mpriv, team_is_ifinfo_changed(ifinfo)))
			continue;
		trunc = team_ifinfo_str(ifinfo, buf, sizeof(buf));
		printf("  %s %s\n", buf, trunc ? "..." : "");
	}
}

static int debug_change_handler_func(struct team_handle *th, void *priv,
				     team_change_type_mask_t type_mask)
{
	struct monitor_priv *mpriv = priv;

	if (type_mask & TEAM_PORT_CHANGE)
		monitor_port_list(th, mpriv);
	if (type_mask & TEAM_OPTION_CHANGE)
		monitor_option_list(th, mpriv);
	if (type_mask & TEAM_IFINFO_CHANGE)
		monitor_ifinfo_list(th, mpriv);
	return 0;
}

static const struct team_change_handler debug_change_handler = {
	.func = debug_change_handler_func,
	.type_mask = TEAM_PORT_CHANGE | TEAM_OPTION_CHANGE | TEAM_IFINFO_CHANGE,
};

static int run_cmd_monitor(char *cmd_name, struct team_handle *th,
			   struct cmd_ctx *cmd_ctx)
{
	struct monitor_priv mpriv;
	int err;

	mpriv.style = MONITOR_STYLE_CHANGED;
	if (cmd_ctx->argc > 0) {
		char *monitor_style_str = cmd_ctx->argv[0];

		if (!strncmp(monitor_style_str, "all",
			     strlen(monitor_style_str))) {
			mpriv.style = MONITOR_STYLE_ALL;
		} else if (!strncmp(monitor_style_str, "changed",
			     strlen(monitor_style_str))) {
			mpriv.style = MONITOR_STYLE_CHANGED;
		} else {
			fprintf(stderr, "Unknown monitor style \"%s\"\n",
					monitor_style_str);
			return -EINVAL;
		}
	}

	err = team_change_handler_register(th, &debug_change_handler, &mpriv);
	if (err) {
		fprintf(stderr, "Failed to register change handler\n");
		return err;
	}
	err = run_main_loop(th);
	team_change_handler_unregister(th, &debug_change_handler, &mpriv);
	return err;
}

static struct cmd_type cmd_types[] = {
	{
		.name = "ports",
		.params = { NULL },
		.run_cmd = run_cmd_ports,
	},
	{
		.name = "options",
		.params = { NULL },
		.run_cmd = run_cmd_options,
	},
	{
		.name = "getoption",
		.params = { "OPT_NAME", NULL },
		.run_cmd = run_cmd_getoption,
	},
	{
		.name = "setoption",
		.params = { "OPT_NAME", "OPT_VALUE", NULL },
		.run_cmd = run_cmd_setoption,
	},
	{
		.name = "monitor",
		.params = { "OPT_STYLE", NULL },
		.run_cmd = run_cmd_monitor,
	},
};
#define CMD_TYPE_COUNT ARRAY_SIZE(cmd_types)

static int process_port_devname_arg(struct team_handle *th,
				    struct cmd_ctx *cmd_ctx)
{
	uint32_t port_ifindex;
	struct team_port *port;

	if (!cmd_ctx->port_devname_arg)
		return 0;
	port_ifindex = team_ifname2ifindex(th, cmd_ctx->port_devname_arg);
	if (!port_ifindex) {
		fprintf(stderr, "Netdevice \"%s\" not found.\n",
			cmd_ctx->port_devname_arg);
		return -ENODEV;
	}
	team_for_each_port(port, th) {
		if (port_ifindex == team_get_port_ifindex(port)) {
			cmd_ctx->port_ifindex_present = true;
			cmd_ctx->port_ifindex = port_ifindex;
			return 0;
		}
	}
	fprintf(stderr, "Netdevice \"%s\" is not port of this team.\n",
			cmd_ctx->port_devname_arg);
	return -ENODEV;
}

static int process_array_index_arg(struct team_handle *th,
				   struct cmd_ctx *cmd_ctx)
{
	uint32_t array_index;
	unsigned long int tmp;
	char *endptr;

	if (!cmd_ctx->array_index_arg)
		return 0;

	tmp = strtoul(cmd_ctx->array_index_arg, &endptr, 10);
	if (tmp == ULONG_MAX) {
		fprintf(stderr, "Failed to parse array index.\n");
		return -errno;
	}
	if (strlen(endptr) != 0) {
		fprintf(stderr, "Failed to parse array index.\n");
		return -EINVAL;
	}
	array_index = tmp;
	if (tmp != array_index) {
		fprintf(stderr, "Array index too big.\n");
		return -ERANGE;
	}
	cmd_ctx->array_index_present = true;
	cmd_ctx->array_index = array_index;
	return 0;
}

static int process_args(struct team_handle *th, struct cmd_ctx *cmd_ctx)
{
	int err;

	err = process_port_devname_arg(th, cmd_ctx);
	if (err)
		return err;
	return process_array_index_arg(th, cmd_ctx);
}

static int call_cmd(char *team_devname, char *cmd_name,
		    struct cmd_ctx *cmd_ctx, run_cmd_t run_cmd)
{
	struct team_handle *th;
	uint32_t ifindex;
	int err;

	th = team_alloc();
	if (!th) {
		fprintf(stderr, "Team alloc failed.\n");
		return -ENOMEM;
	}

	ifindex = team_ifname2ifindex(th, team_devname);
	if (!ifindex) {
		fprintf(stderr, "Netdevice \"%s\" not found.\n", team_devname);
		err = -ENODEV;
		goto team_free;
	}

	err = team_init(th, ifindex);
	if (err) {
		fprintf(stderr, "Team init failed.\n");
		goto team_free;
	}

	err = process_args(th, cmd_ctx);
	if (err)
		goto team_free;

	err = run_cmd(cmd_name, th, cmd_ctx);

team_free:
	team_free(th);
	return err;
}

static void print_help(const char *argv0) {
	int i, j;

	printf(
            "%s [options] teamdevname command [command args]\n"
            "\t-h --help                Show this help\n",
            argv0);
	printf("Commands:\n");
	for (i = 0; i < CMD_TYPE_COUNT; i++) {
		printf("\t%s", cmd_types[i].name);
		for (j = 0; cmd_types[i].params[j]; j++)
			printf(" %s", cmd_types[i].params[j]);
		printf("\n");
	}
}

int main(int argc, char **argv)
{
	char *argv0 = argv[0];
	char *team_devname;
	char *cmd_name;
	struct cmd_ctx cmd_ctx;
	static const struct option long_options[] = {
		{ "help",		no_argument,		NULL, 'h' },
		{ "port_name",		required_argument,	NULL, 'p' },
		{ "array_index",	required_argument,	NULL, 'a' },
		{ NULL, 0, NULL, 0 }
	};
	int opt;
	int err;
	int i;
	int res = EXIT_FAILURE;

	memset(&cmd_ctx, 0, sizeof(cmd_ctx));

	while ((opt = getopt_long(argc, argv, "hp:a:",
				  long_options, NULL)) >= 0) {

		switch(opt) {
		case 'h':
			print_help(argv0);
			return EXIT_SUCCESS;
		case 'p':
			free(cmd_ctx.port_devname_arg);
			cmd_ctx.port_devname_arg = strdup(optarg);
			break;
		case 'a':
			free(cmd_ctx.array_index_arg);
			cmd_ctx.array_index_arg = strdup(optarg);
			break;
		case '?':
			fprintf(stderr, "unknown option.\n");
			print_help(argv0);
			return EXIT_FAILURE;
		default:
			fprintf(stderr, "unknown option \"%c\".\n", opt);
			print_help(argv0);
			return EXIT_FAILURE;
		}
	}

	if (optind >= argc) {
		fprintf(stderr, "No team device specified.\n");
		printf("\n");
		print_help(argv0);
		goto errout;
	}
	if (optind + 1 >= argc) {
		fprintf(stderr, "No command specified.\n");
		printf("\n");
		print_help(argv0);
		goto errout;
	}

	argv += optind;
	team_devname = *argv++;
	cmd_name = *argv++;
	argc -= optind + 2;
	cmd_ctx.argc = argc;
	cmd_ctx.argv = argv;
	for (i = 0; i < CMD_TYPE_COUNT; i++) {
		if (strncmp(cmd_types[i].name, cmd_name, strlen(cmd_name)))
			continue;
		err = call_cmd(team_devname, cmd_name, &cmd_ctx,
			       cmd_types[i].run_cmd);
		if (err) {
			fprintf(stderr, "Command failed: %s\n", strerror(-err));
			goto errout;
		}
		break;
	}
	if (i == CMD_TYPE_COUNT) {
		fprintf(stderr, "Unknown command \"%s\".\n", cmd_name);
		printf("\n");
		print_help(argv0);
		goto errout;
	}
	res = EXIT_SUCCESS;
errout:
	free(cmd_ctx.port_devname_arg);
	free(cmd_ctx.array_index_arg);
	return res;
}
