// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <sched.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include "log.h"
#include "timens.h"

/*
 * Test shouldn't be run for a day, so add 10 days to child
 * time and check parent's time to be in the same day.
 */
#define MAX_TEST_TIME_SEC		(60*5)
#define DAY_IN_SEC			(60*60*24)
#define TEN_DAYS_IN_SEC			(10*DAY_IN_SEC)

static int child_ns, parent_ns;

static int switch_ns(int fd)
{
	if (setns(fd, CLONE_NEWTIME))
		return pr_perror("setns()");

	return 0;
}

static int init_namespaces(void)
{
	char path[] = "/proc/self/ns/time_for_children";
	struct stat st1, st2;

	parent_ns = open(path, O_RDONLY);
	if (parent_ns <= 0)
		return pr_perror("Unable to open %s", path);

	if (fstat(parent_ns, &st1))
		return pr_perror("Unable to stat the parent timens");

	if (unshare_timens())
		return -1;

	child_ns = open(path, O_RDONLY);
	if (child_ns <= 0)
		return pr_perror("Unable to open %s", path);

	if (fstat(child_ns, &st2))
		return pr_perror("Unable to stat the timens");

	if (st1.st_ino == st2.st_ino)
		return pr_err("The same child_ns after CLONE_NEWTIME");

	if (_settime(CLOCK_BOOTTIME, TEN_DAYS_IN_SEC))
		return -1;

	return 0;
}

static int read_proc_uptime(struct timespec *uptime)
{
	unsigned long up_sec, up_nsec;
	FILE *proc;

	proc = fopen("/proc/uptime", "r");
	if (proc == NULL) {
		pr_perror("Unable to open /proc/uptime");
		return -1;
	}

	if (fscanf(proc, "%lu.%02lu", &up_sec, &up_nsec) != 2) {
		if (errno) {
			pr_perror("fscanf");
			return -errno;
		}
		pr_err("failed to parse /proc/uptime");
		return -1;
	}
	fclose(proc);

	uptime->tv_sec = up_sec;
	uptime->tv_nsec = up_nsec;
	return 0;
}

static int read_proc_stat_btime(unsigned long long *boottime_sec)
{
	FILE *proc;
	char line_buf[2048];

	proc = fopen("/proc/stat", "r");
	if (proc == NULL) {
		pr_perror("Unable to open /proc/stat");
		return -1;
	}

	while (fgets(line_buf, 2048, proc)) {
		if (sscanf(line_buf, "btime %llu", boottime_sec) != 1)
			continue;
		fclose(proc);
		return 0;
	}
	if (errno) {
		pr_perror("fscanf");
		fclose(proc);
		return -errno;
	}
	pr_err("failed to parse /proc/stat");
	fclose(proc);
	return -1;
}

static int check_uptime(void)
{
	struct timespec uptime_new, uptime_old;
	time_t uptime_expected;
	double prec = MAX_TEST_TIME_SEC;

	if (switch_ns(parent_ns))
		return pr_err("switch_ns(%d)", parent_ns);

	if (read_proc_uptime(&uptime_old))
		return 1;

	if (switch_ns(child_ns))
		return pr_err("switch_ns(%d)", child_ns);

	if (read_proc_uptime(&uptime_new))
		return 1;

	uptime_expected = uptime_old.tv_sec + TEN_DAYS_IN_SEC;
	if (fabs(difftime(uptime_new.tv_sec, uptime_expected)) > prec) {
		pr_fail("uptime in /proc/uptime: old %ld, new %ld [%ld]",
			uptime_old.tv_sec, uptime_new.tv_sec,
			uptime_old.tv_sec + TEN_DAYS_IN_SEC);
		return 1;
	}

	ksft_test_result_pass("Passed for /proc/uptime\n");
	return 0;
}

static int check_stat_btime(void)
{
	unsigned long long btime_new, btime_old;
	unsigned long long btime_expected;

	if (switch_ns(parent_ns))
		return pr_err("switch_ns(%d)", parent_ns);

	if (read_proc_stat_btime(&btime_old))
		return 1;

	if (switch_ns(child_ns))
		return pr_err("switch_ns(%d)", child_ns);

	if (read_proc_stat_btime(&btime_new))
		return 1;

	btime_expected = btime_old - TEN_DAYS_IN_SEC;
	if (btime_new != btime_expected) {
		pr_fail("btime in /proc/stat: old %llu, new %llu [%llu]",
			btime_old, btime_new, btime_expected);
		return 1;
	}

	ksft_test_result_pass("Passed for /proc/stat btime\n");
	return 0;
}

int main(int argc, char *argv[])
{
	int ret = 0;

	nscheck();

	ksft_set_plan(2);

	if (init_namespaces())
		return 1;

	ret |= check_uptime();
	ret |= check_stat_btime();

	if (ret)
		ksft_exit_fail();
	ksft_exit_pass();
	return ret;
}
