// SPDX-License-Identifier: GPL-2.0
#include <inttypes.h>
#include <pthread.h>
#include <stdio.h>
#include "../../../../../include/linux/compiler.h"
#include "../../../../../include/linux/kernel.h"
#include "aolib.h"

struct netstat_counter {
	uint64_t val;
	char *name;
};

struct netstat {
	char *header_name;
	struct netstat *next;
	size_t counters_nr;
	struct netstat_counter *counters;
};

static struct netstat *lookup_type(struct netstat *ns,
		const char *type, size_t len)
{
	while (ns != NULL) {
		size_t cmp = max(len, strlen(ns->header_name));

		if (!strncmp(ns->header_name, type, cmp))
			return ns;
		ns = ns->next;
	}
	return NULL;
}

static struct netstat *lookup_get(struct netstat *ns,
				  const char *type, const size_t len)
{
	struct netstat *ret;

	ret = lookup_type(ns, type, len);
	if (ret != NULL)
		return ret;

	ret = malloc(sizeof(struct netstat));
	if (!ret)
		test_error("malloc()");

	ret->header_name = strndup(type, len);
	if (ret->header_name == NULL)
		test_error("strndup()");
	ret->next = ns;
	ret->counters_nr = 0;
	ret->counters = NULL;

	return ret;
}

static struct netstat *lookup_get_column(struct netstat *ns, const char *line)
{
	char *column;

	column = strchr(line, ':');
	if (!column)
		test_error("can't parse netstat file");

	return lookup_get(ns, line, column - line);
}

static void netstat_read_type(FILE *fnetstat, struct netstat **dest, char *line)
{
	struct netstat *type = lookup_get_column(*dest, line);
	const char *pos = line;
	size_t i, nr_elems = 0;
	char tmp;

	while ((pos = strchr(pos, ' '))) {
		nr_elems++;
		pos++;
	}

	*dest = type;
	type->counters = reallocarray(type->counters,
				type->counters_nr + nr_elems,
				sizeof(struct netstat_counter));
	if (!type->counters)
		test_error("reallocarray()");

	pos = strchr(line, ' ') + 1;

	if (fscanf(fnetstat, "%[^ :]", type->header_name) == EOF)
		test_error("fscanf(%s)", type->header_name);
	if (fread(&tmp, 1, 1, fnetstat) != 1 || tmp != ':')
		test_error("Unexpected netstat format (%c)", tmp);

	for (i = type->counters_nr; i < type->counters_nr + nr_elems; i++) {
		struct netstat_counter *nc = &type->counters[i];
		const char *new_pos = strchr(pos, ' ');
		const char *fmt = " %" PRIu64;

		if (new_pos == NULL)
			new_pos = strchr(pos, '\n');

		nc->name = strndup(pos, new_pos - pos);
		if (nc->name == NULL)
			test_error("strndup()");

		if (unlikely(!strcmp(nc->name, "MaxConn")))
			fmt = " %" PRId64; /* MaxConn is signed, RFC 2012 */
		if (fscanf(fnetstat, fmt, &nc->val) != 1)
			test_error("fscanf(%s)", nc->name);
		pos = new_pos + 1;
	}
	type->counters_nr += nr_elems;

	if (fread(&tmp, 1, 1, fnetstat) != 1 || tmp != '\n')
		test_error("Unexpected netstat format");
}

static const char *snmp6_name = "Snmp6";
static void snmp6_read(FILE *fnetstat, struct netstat **dest)
{
	struct netstat *type = lookup_get(*dest, snmp6_name, strlen(snmp6_name));
	char *counter_name;
	size_t i;

	for (i = type->counters_nr;; i++) {
		struct netstat_counter *nc;
		uint64_t counter;

		if (fscanf(fnetstat, "%ms", &counter_name) == EOF)
			break;
		if (fscanf(fnetstat, "%" PRIu64, &counter) == EOF)
			test_error("Unexpected snmp6 format");
		type->counters = reallocarray(type->counters, i + 1,
					sizeof(struct netstat_counter));
		if (!type->counters)
			test_error("reallocarray()");
		nc = &type->counters[i];
		nc->name = counter_name;
		nc->val = counter;
	}
	type->counters_nr = i;
	*dest = type;
}

struct netstat *netstat_read(void)
{
	struct netstat *ret = 0;
	size_t line_sz = 0;
	char *line = NULL;
	FILE *fnetstat;

	/*
	 * Opening thread-self instead of /proc/net/... as the latter
	 * points to /proc/self/net/ which instantiates thread-leader's
	 * net-ns, see:
	 * commit 155134fef2b6 ("Revert "proc: Point /proc/{mounts,net} at..")
	 */
	errno = 0;
	fnetstat = fopen("/proc/thread-self/net/netstat", "r");
	if (fnetstat == NULL)
		test_error("failed to open /proc/net/netstat");

	while (getline(&line, &line_sz, fnetstat) != -1)
		netstat_read_type(fnetstat, &ret, line);
	fclose(fnetstat);

	errno = 0;
	fnetstat = fopen("/proc/thread-self/net/snmp", "r");
	if (fnetstat == NULL)
		test_error("failed to open /proc/net/snmp");

	while (getline(&line, &line_sz, fnetstat) != -1)
		netstat_read_type(fnetstat, &ret, line);
	fclose(fnetstat);

	errno = 0;
	fnetstat = fopen("/proc/thread-self/net/snmp6", "r");
	if (fnetstat == NULL)
		test_error("failed to open /proc/net/snmp6");

	snmp6_read(fnetstat, &ret);
	fclose(fnetstat);

	free(line);
	return ret;
}

void netstat_free(struct netstat *ns)
{
	while (ns != NULL) {
		struct netstat *prev = ns;
		size_t i;

		free(ns->header_name);
		for (i = 0; i < ns->counters_nr; i++)
			free(ns->counters[i].name);
		free(ns->counters);
		ns = ns->next;
		free(prev);
	}
}

static inline void
__netstat_print_diff(uint64_t a, struct netstat *nsb, size_t i)
{
	if (unlikely(!strcmp(nsb->header_name, "MaxConn"))) {
		test_print("%8s %25s: %" PRId64 " => %" PRId64,
				nsb->header_name, nsb->counters[i].name,
				a, nsb->counters[i].val);
		return;
	}

	test_print("%8s %25s: %" PRIu64 " => %" PRIu64, nsb->header_name,
			nsb->counters[i].name, a, nsb->counters[i].val);
}

void netstat_print_diff(struct netstat *nsa, struct netstat *nsb)
{
	size_t i, j;

	while (nsb != NULL) {
		if (unlikely(strcmp(nsb->header_name, nsa->header_name))) {
			for (i = 0; i < nsb->counters_nr; i++)
				__netstat_print_diff(0, nsb, i);
			nsb = nsb->next;
			continue;
		}

		if (nsb->counters_nr < nsa->counters_nr)
			test_error("Unexpected: some counters disappeared!");

		for (j = 0, i = 0; i < nsb->counters_nr; i++) {
			if (strcmp(nsb->counters[i].name, nsa->counters[j].name)) {
				__netstat_print_diff(0, nsb, i);
				continue;
			}

			if (nsa->counters[j].val == nsb->counters[i].val) {
				j++;
				continue;
			}

			__netstat_print_diff(nsa->counters[j].val, nsb, i);
			j++;
		}
		if (j != nsa->counters_nr)
			test_error("Unexpected: some counters disappeared!");

		nsb = nsb->next;
		nsa = nsa->next;
	}
}

uint64_t netstat_get(struct netstat *ns, const char *name, bool *not_found)
{
	if (not_found)
		*not_found = false;

	while (ns != NULL) {
		size_t i;

		for (i = 0; i < ns->counters_nr; i++) {
			if (!strcmp(name, ns->counters[i].name))
				return ns->counters[i].val;
		}

		ns = ns->next;
	}

	if (not_found)
		*not_found = true;
	return 0;
}
