/*
 * Strictly speaking, this is not a test. But it can report during test
 * runs so relative performace can be measured.
 */
#define _GNU_SOURCE
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <sys/param.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <sys/types.h>

#include "../kselftest.h"

unsigned long long timing(clockid_t clk_id, unsigned long long samples)
{
	struct timespec start, finish;
	unsigned long long i;
	pid_t pid, ret;

	pid = getpid();
	assert(clock_gettime(clk_id, &start) == 0);
	for (i = 0; i < samples; i++) {
		ret = syscall(__NR_getpid);
		assert(pid == ret);
	}
	assert(clock_gettime(clk_id, &finish) == 0);

	i = finish.tv_sec - start.tv_sec;
	i *= 1000000000ULL;
	i += finish.tv_nsec - start.tv_nsec;

	printf("%lu.%09lu - %lu.%09lu = %llu (%.1fs)\n",
		finish.tv_sec, finish.tv_nsec,
		start.tv_sec, start.tv_nsec,
		i, (double)i / 1000000000.0);

	return i;
}

unsigned long long calibrate(void)
{
	struct timespec start, finish;
	unsigned long long i, samples, step = 9973;
	pid_t pid, ret;
	int seconds = 15;

	printf("Calibrating sample size for %d seconds worth of syscalls ...\n", seconds);

	samples = 0;
	pid = getpid();
	assert(clock_gettime(CLOCK_MONOTONIC, &start) == 0);
	do {
		for (i = 0; i < step; i++) {
			ret = syscall(__NR_getpid);
			assert(pid == ret);
		}
		assert(clock_gettime(CLOCK_MONOTONIC, &finish) == 0);

		samples += step;
		i = finish.tv_sec - start.tv_sec;
		i *= 1000000000ULL;
		i += finish.tv_nsec - start.tv_nsec;
	} while (i < 1000000000ULL);

	return samples * seconds;
}

bool approx(int i_one, int i_two)
{
	double one = i_one, one_bump = one * 0.01;
	double two = i_two, two_bump = two * 0.01;

	one_bump = one + MAX(one_bump, 2.0);
	two_bump = two + MAX(two_bump, 2.0);

	/* Equal to, or within 1% or 2 digits */
	if (one == two ||
	    (one > two && one <= two_bump) ||
	    (two > one && two <= one_bump))
		return true;
	return false;
}

bool le(int i_one, int i_two)
{
	if (i_one <= i_two)
		return true;
	return false;
}

long compare(const char *name_one, const char *name_eval, const char *name_two,
	     unsigned long long one, bool (*eval)(int, int), unsigned long long two)
{
	bool good;

	printf("\t%s %s %s (%lld %s %lld): ", name_one, name_eval, name_two,
	       (long long)one, name_eval, (long long)two);
	if (one > INT_MAX) {
		printf("Miscalculation! Measurement went negative: %lld\n", (long long)one);
		return 1;
	}
	if (two > INT_MAX) {
		printf("Miscalculation! Measurement went negative: %lld\n", (long long)two);
		return 1;
	}

	good = eval(one, two);
	printf("%s\n", good ? "✔️" : "❌");

	return good ? 0 : 1;
}

int main(int argc, char *argv[])
{
	struct sock_filter bitmap_filter[] = {
		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, offsetof(struct seccomp_data, nr)),
		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
	};
	struct sock_fprog bitmap_prog = {
		.len = (unsigned short)ARRAY_SIZE(bitmap_filter),
		.filter = bitmap_filter,
	};
	struct sock_filter filter[] = {
		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, offsetof(struct seccomp_data, args[0])),
		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
	};
	struct sock_fprog prog = {
		.len = (unsigned short)ARRAY_SIZE(filter),
		.filter = filter,
	};

	long ret, bits;
	unsigned long long samples, calc;
	unsigned long long native, filter1, filter2, bitmap1, bitmap2;
	unsigned long long entry, per_filter1, per_filter2;

	setbuf(stdout, NULL);

	printf("Running on:\n");
	system("uname -a");

	printf("Current BPF sysctl settings:\n");
	/* Avoid using "sysctl" which may not be installed. */
	system("grep -H . /proc/sys/net/core/bpf_jit_enable");
	system("grep -H . /proc/sys/net/core/bpf_jit_harden");

	if (argc > 1)
		samples = strtoull(argv[1], NULL, 0);
	else
		samples = calibrate();

	printf("Benchmarking %llu syscalls...\n", samples);

	/* Native call */
	native = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
	printf("getpid native: %llu ns\n", native);

	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
	assert(ret == 0);

	/* One filter resulting in a bitmap */
	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &bitmap_prog);
	assert(ret == 0);

	bitmap1 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
	printf("getpid RET_ALLOW 1 filter (bitmap): %llu ns\n", bitmap1);

	/* Second filter resulting in a bitmap */
	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &bitmap_prog);
	assert(ret == 0);

	bitmap2 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
	printf("getpid RET_ALLOW 2 filters (bitmap): %llu ns\n", bitmap2);

	/* Third filter, can no longer be converted to bitmap */
	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
	assert(ret == 0);

	filter1 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
	printf("getpid RET_ALLOW 3 filters (full): %llu ns\n", filter1);

	/* Fourth filter, can not be converted to bitmap because of filter 3 */
	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &bitmap_prog);
	assert(ret == 0);

	filter2 = timing(CLOCK_PROCESS_CPUTIME_ID, samples) / samples;
	printf("getpid RET_ALLOW 4 filters (full): %llu ns\n", filter2);

	/* Estimations */
#define ESTIMATE(fmt, var, what)	do {			\
		var = (what);					\
		printf("Estimated " fmt ": %llu ns\n", var);	\
		if (var > INT_MAX)				\
			goto more_samples;			\
	} while (0)

	ESTIMATE("total seccomp overhead for 1 bitmapped filter", calc,
		 bitmap1 - native);
	ESTIMATE("total seccomp overhead for 2 bitmapped filters", calc,
		 bitmap2 - native);
	ESTIMATE("total seccomp overhead for 3 full filters", calc,
		 filter1 - native);
	ESTIMATE("total seccomp overhead for 4 full filters", calc,
		 filter2 - native);
	ESTIMATE("seccomp entry overhead", entry,
		 bitmap1 - native - (bitmap2 - bitmap1));
	ESTIMATE("seccomp per-filter overhead (last 2 diff)", per_filter1,
		 filter2 - filter1);
	ESTIMATE("seccomp per-filter overhead (filters / 4)", per_filter2,
		 (filter2 - native - entry) / 4);

	printf("Expectations:\n");
	ret |= compare("native", "≤", "1 bitmap", native, le, bitmap1);
	bits = compare("native", "≤", "1 filter", native, le, filter1);
	if (bits)
		goto more_samples;

	ret |= compare("per-filter (last 2 diff)", "≈", "per-filter (filters / 4)",
			per_filter1, approx, per_filter2);

	bits = compare("1 bitmapped", "≈", "2 bitmapped",
			bitmap1 - native, approx, bitmap2 - native);
	if (bits) {
		printf("Skipping constant action bitmap expectations: they appear unsupported.\n");
		goto out;
	}

	ret |= compare("entry", "≈", "1 bitmapped", entry, approx, bitmap1 - native);
	ret |= compare("entry", "≈", "2 bitmapped", entry, approx, bitmap2 - native);
	ret |= compare("native + entry + (per filter * 4)", "≈", "4 filters total",
			entry + (per_filter1 * 4) + native, approx, filter2);
	if (ret == 0)
		goto out;

more_samples:
	printf("Saw unexpected benchmark result. Try running again with more samples?\n");
out:
	return 0;
}
