/*
 * tc_class.c		"tc class".
 *
 *		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.
 *
 * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <math.h>

#include "utils.h"
#include "tc_util.h"
#include "tc_common.h"
#include "list.h"

struct graph_node {
	struct hlist_node hlist;
	__u32 id;
	__u32 parent_id;
	struct graph_node *parent_node;
	struct graph_node *right_node;
	void *data;
	int data_len;
	int nodes_count;
};

static struct hlist_head cls_list = {};
static struct hlist_head root_cls_list = {};

static void usage(void);

static void usage(void)
{
	fprintf(stderr, "Usage: tc class [ add | del | change | replace | show ] dev STRING\n");
	fprintf(stderr, "       [ classid CLASSID ] [ root | parent CLASSID ]\n");
	fprintf(stderr, "       [ [ QDISC_KIND ] [ help | OPTIONS ] ]\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "       tc class show [ dev STRING ] [ root | parent CLASSID ]\n");
	fprintf(stderr, "Where:\n");
	fprintf(stderr, "QDISC_KIND := { prio | cbq | etc. }\n");
	fprintf(stderr, "OPTIONS := ... try tc class add <desired QDISC_KIND> help\n");
}

static int tc_class_modify(int cmd, unsigned int flags, int argc, char **argv)
{
	struct {
		struct nlmsghdr	n;
		struct tcmsg		t;
		char			buf[4096];
	} req = {
		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)),
		.n.nlmsg_flags = NLM_F_REQUEST | flags,
		.n.nlmsg_type = cmd,
		.t.tcm_family = AF_UNSPEC,
	};
	struct qdisc_util *q = NULL;
	struct tc_estimator est = {};
	char  d[16] = {};
	char  k[16] = {};

	while (argc > 0) {
		if (strcmp(*argv, "dev") == 0) {
			NEXT_ARG();
			if (d[0])
				duparg("dev", *argv);
			strncpy(d, *argv, sizeof(d)-1);
		} else if (strcmp(*argv, "classid") == 0) {
			__u32 handle;

			NEXT_ARG();
			if (req.t.tcm_handle)
				duparg("classid", *argv);
			if (get_tc_classid(&handle, *argv))
				invarg("invalid class ID", *argv);
			req.t.tcm_handle = handle;
		} else if (strcmp(*argv, "handle") == 0) {
			fprintf(stderr, "Error: try \"classid\" instead of \"handle\"\n");
			return -1;
		} else if (strcmp(*argv, "root") == 0) {
			if (req.t.tcm_parent) {
				fprintf(stderr, "Error: \"root\" is duplicate parent ID.\n");
				return -1;
			}
			req.t.tcm_parent = TC_H_ROOT;
		} else if (strcmp(*argv, "parent") == 0) {
			__u32 handle;

			NEXT_ARG();
			if (req.t.tcm_parent)
				duparg("parent", *argv);
			if (get_tc_classid(&handle, *argv))
				invarg("invalid parent ID", *argv);
			req.t.tcm_parent = handle;
		} else if (matches(*argv, "estimator") == 0) {
			if (parse_estimator(&argc, &argv, &est))
				return -1;
		} else if (matches(*argv, "help") == 0) {
			usage();
		} else {
			strncpy(k, *argv, sizeof(k)-1);

			q = get_qdisc_kind(k);
			argc--; argv++;
			break;
		}
		argc--; argv++;
	}

	if (k[0])
		addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1);
	if (est.ewma_log)
		addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est));

	if (q) {
		if (q->parse_copt == NULL) {
			fprintf(stderr, "Error: Qdisc \"%s\" is classless.\n", k);
			return 1;
		}
		if (q->parse_copt(q, argc, argv, &req.n))
			return 1;
	} else {
		if (argc) {
			if (matches(*argv, "help") == 0)
				usage();
			fprintf(stderr, "Garbage instead of arguments \"%s ...\". Try \"tc class help\".", *argv);
			return -1;
		}
	}

	if (d[0])  {
		ll_init_map(&rth);

		if ((req.t.tcm_ifindex = ll_name_to_index(d)) == 0) {
			fprintf(stderr, "Cannot find device \"%s\"\n", d);
			return 1;
		}
	}

	if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
		return 2;

	return 0;
}

int filter_ifindex;
__u32 filter_qdisc;
__u32 filter_classid;

static void graph_node_add(__u32 parent_id, __u32 id, void *data,
		int len)
{
	struct graph_node *node = calloc(1, sizeof(struct graph_node));

	node->id         = id;
	node->parent_id  = parent_id;

	if (data && len) {
		node->data       = malloc(len);
		node->data_len   = len;
		memcpy(node->data, data, len);
	}

	if (parent_id == TC_H_ROOT)
		hlist_add_head(&node->hlist, &root_cls_list);
	else
		hlist_add_head(&node->hlist, &cls_list);
}

static void graph_indent(char *buf, struct graph_node *node, int is_newline,
		int add_spaces)
{
	char spaces[100] = {0};

	while (node && node->parent_node) {
		node->parent_node->right_node = node;
		node = node->parent_node;
	}
	while (node && node->right_node) {
		if (node->hlist.next)
			strcat(buf, "|    ");
		else
			strcat(buf, "     ");

		node = node->right_node;
	}

	if (is_newline) {
		if (node->hlist.next && node->nodes_count)
			strcat(buf, "|    |");
		else if (node->hlist.next)
			strcat(buf, "|     ");
		else if (node->nodes_count)
			strcat(buf, "     |");
		else if (!node->hlist.next)
			strcat(buf, "      ");
	}
	if (add_spaces > 0) {
		sprintf(spaces, "%-*s", add_spaces, "");
		strcat(buf, spaces);
	}
}

static void graph_cls_show(FILE *fp, char *buf, struct hlist_head *root_list,
		int level)
{
	struct hlist_node *n, *tmp_cls;
	char cls_id_str[256] = {};
	struct rtattr *tb[TCA_MAX + 1];
	struct qdisc_util *q;
	char str[100] = {};

	hlist_for_each_safe(n, tmp_cls, root_list) {
		struct hlist_node *c, *tmp_chld;
		struct hlist_head children = {};
		struct graph_node *cls = container_of(n, struct graph_node,
				hlist);

		hlist_for_each_safe(c, tmp_chld, &cls_list) {
			struct graph_node *child = container_of(c,
					struct graph_node, hlist);

			if (cls->id == child->parent_id) {
				hlist_del(c);
				hlist_add_head(c, &children);
				cls->nodes_count++;
				child->parent_node = cls;
			}
		}

		graph_indent(buf, cls, 0, 0);

		print_tc_classid(cls_id_str, sizeof(cls_id_str), cls->id);
		sprintf(str, "+---(%s)", cls_id_str);
		strcat(buf, str);

		parse_rtattr(tb, TCA_MAX, (struct rtattr *)cls->data,
				cls->data_len);

		if (tb[TCA_KIND] == NULL) {
			strcat(buf, " [unknown qdisc kind] ");
		} else {
			const char *kind = rta_getattr_str(tb[TCA_KIND]);

			sprintf(str, " %s ", kind);
			strcat(buf, str);
			fprintf(fp, "%s", buf);
			buf[0] = '\0';

			q = get_qdisc_kind(kind);
			if (q && q->print_copt) {
				q->print_copt(q, fp, tb[TCA_OPTIONS]);
			}
			if (q && show_stats) {
				int cls_indent = strlen(q->id) - 2 +
					strlen(cls_id_str);
				struct rtattr *stats = NULL;

				graph_indent(buf, cls, 1, cls_indent);

				if (tb[TCA_STATS] || tb[TCA_STATS2]) {
					fprintf(fp, "\n");
					print_tcstats_attr(fp, tb, buf, &stats);
					buf[0] = '\0';
				}
				if (cls->hlist.next || cls->nodes_count) {
					strcat(buf, "\n");
					graph_indent(buf, cls, 1, 0);
				}
			}
		}
		free(cls->data);
		fprintf(fp, "%s\n", buf);
		buf[0] = '\0';

		graph_cls_show(fp, buf, &children, level + 1);
		if (!cls->hlist.next) {
			graph_indent(buf, cls, 0, 0);
			strcat(buf, "\n");
		}

		fprintf(fp, "%s", buf);
		buf[0] = '\0';
		free(cls);
	}
}

int print_class(const struct sockaddr_nl *who,
		       struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE *)arg;
	struct tcmsg *t = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr *tb[TCA_MAX + 1];
	struct qdisc_util *q;
	char abuf[256];

	if (n->nlmsg_type != RTM_NEWTCLASS && n->nlmsg_type != RTM_DELTCLASS) {
		fprintf(stderr, "Not a class\n");
		return 0;
	}
	len -= NLMSG_LENGTH(sizeof(*t));
	if (len < 0) {
		fprintf(stderr, "Wrong len %d\n", len);
		return -1;
	}

	if (show_graph) {
		graph_node_add(t->tcm_parent, t->tcm_handle, TCA_RTA(t), len);
		return 0;
	}

	if (filter_qdisc && TC_H_MAJ(t->tcm_handle^filter_qdisc))
		return 0;

	if (filter_classid && t->tcm_handle != filter_classid)
		return 0;

	parse_rtattr(tb, TCA_MAX, TCA_RTA(t), len);

	if (tb[TCA_KIND] == NULL) {
		fprintf(stderr, "print_class: NULL kind\n");
		return -1;
	}

	if (n->nlmsg_type == RTM_DELTCLASS)
		fprintf(fp, "deleted ");

	abuf[0] = 0;
	if (t->tcm_handle) {
		if (filter_qdisc)
			print_tc_classid(abuf, sizeof(abuf), TC_H_MIN(t->tcm_handle));
		else
			print_tc_classid(abuf, sizeof(abuf), t->tcm_handle);
	}
	fprintf(fp, "class %s %s ", rta_getattr_str(tb[TCA_KIND]), abuf);

	if (filter_ifindex == 0)
		fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex));

	if (t->tcm_parent == TC_H_ROOT)
		fprintf(fp, "root ");
	else {
		if (filter_qdisc)
			print_tc_classid(abuf, sizeof(abuf), TC_H_MIN(t->tcm_parent));
		else
			print_tc_classid(abuf, sizeof(abuf), t->tcm_parent);
		fprintf(fp, "parent %s ", abuf);
	}
	if (t->tcm_info)
		fprintf(fp, "leaf %x: ", t->tcm_info>>16);
	q = get_qdisc_kind(RTA_DATA(tb[TCA_KIND]));
	if (tb[TCA_OPTIONS]) {
		if (q && q->print_copt)
			q->print_copt(q, fp, tb[TCA_OPTIONS]);
		else
			fprintf(fp, "[cannot parse class parameters]");
	}
	fprintf(fp, "\n");
	if (show_stats) {
		struct rtattr *xstats = NULL;

		if (tb[TCA_STATS] || tb[TCA_STATS2]) {
			print_tcstats_attr(fp, tb, " ", &xstats);
			fprintf(fp, "\n");
		}
		if (q && (xstats || tb[TCA_XSTATS]) && q->print_xstats) {
			q->print_xstats(q, fp, xstats ? : tb[TCA_XSTATS]);
			fprintf(fp, "\n");
		}
	}
	fflush(fp);
	return 0;
}


static int tc_class_list(int argc, char **argv)
{
	struct tcmsg t = { .tcm_family = AF_UNSPEC };
	char d[16] = {};
	char buf[1024] = {0};

	filter_qdisc = 0;
	filter_classid = 0;

	while (argc > 0) {
		if (strcmp(*argv, "dev") == 0) {
			NEXT_ARG();
			if (d[0])
				duparg("dev", *argv);
			strncpy(d, *argv, sizeof(d)-1);
		} else if (strcmp(*argv, "qdisc") == 0) {
			NEXT_ARG();
			if (filter_qdisc)
				duparg("qdisc", *argv);
			if (get_qdisc_handle(&filter_qdisc, *argv))
				invarg("invalid qdisc ID", *argv);
		} else if (strcmp(*argv, "classid") == 0) {
			NEXT_ARG();
			if (filter_classid)
				duparg("classid", *argv);
			if (get_tc_classid(&filter_classid, *argv))
				invarg("invalid class ID", *argv);
		} else if (strcmp(*argv, "root") == 0) {
			if (t.tcm_parent) {
				fprintf(stderr, "Error: \"root\" is duplicate parent ID\n");
				return -1;
			}
			t.tcm_parent = TC_H_ROOT;
		} else if (strcmp(*argv, "parent") == 0) {
			__u32 handle;

			if (t.tcm_parent)
				duparg("parent", *argv);
			NEXT_ARG();
			if (get_tc_classid(&handle, *argv))
				invarg("invalid parent ID", *argv);
			t.tcm_parent = handle;
		} else if (matches(*argv, "help") == 0) {
			usage();
		} else {
			fprintf(stderr, "What is \"%s\"? Try \"tc class help\".\n", *argv);
			return -1;
		}

		argc--; argv++;
	}

	ll_init_map(&rth);

	if (d[0]) {
		if ((t.tcm_ifindex = ll_name_to_index(d)) == 0) {
			fprintf(stderr, "Cannot find device \"%s\"\n", d);
			return 1;
		}
		filter_ifindex = t.tcm_ifindex;
	}

	if (rtnl_dump_request(&rth, RTM_GETTCLASS, &t, sizeof(t)) < 0) {
		perror("Cannot send dump request");
		return 1;
	}

	if (rtnl_dump_filter(&rth, print_class, stdout) < 0) {
		fprintf(stderr, "Dump terminated\n");
		return 1;
	}

	if (show_graph)
		graph_cls_show(stdout, &buf[0], &root_cls_list, 0);

	return 0;
}

int do_class(int argc, char **argv)
{
	if (argc < 1)
		return tc_class_list(0, NULL);
	if (matches(*argv, "add") == 0)
		return tc_class_modify(RTM_NEWTCLASS, NLM_F_EXCL|NLM_F_CREATE, argc-1, argv+1);
	if (matches(*argv, "change") == 0)
		return tc_class_modify(RTM_NEWTCLASS, 0, argc-1, argv+1);
	if (matches(*argv, "replace") == 0)
		return tc_class_modify(RTM_NEWTCLASS, NLM_F_CREATE, argc-1, argv+1);
	if (matches(*argv, "delete") == 0)
		return tc_class_modify(RTM_DELTCLASS, 0,  argc-1, argv+1);
#if 0
	if (matches(*argv, "get") == 0)
		return tc_class_get(RTM_GETTCLASS, 0,  argc-1, argv+1);
#endif
	if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
	    || matches(*argv, "lst") == 0)
		return tc_class_list(argc-1, argv+1);
	if (matches(*argv, "help") == 0) {
		usage();
		return 0;
	}
	fprintf(stderr, "Command \"%s\" is unknown, try \"tc class help\".\n", *argv);
	return -1;
}
