// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2020 Google LLC
 */
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <unistd.h>

#include "utils.h"

#define err_msg(...)                                                           \
	do {                                                                   \
		fprintf(stderr, "%s: (%d) ", TAG, __LINE__);                   \
		fprintf(stderr, __VA_ARGS__);                                  \
		fprintf(stderr, " (%s)\n", strerror(errno));                   \
	} while (false)

#define TAG "incfs_stress"

struct options {
	bool no_cleanup; /* -c */
	const char *test_dir; /* -d */
	unsigned int rng_seed; /* -g */
	int num_reads; /* -n */
	int readers; /* -r */
	int size; /* -s */
	int timeout; /* -t */
};

struct read_data {
	const char *filename;
	int dir_fd;
	size_t filesize;
	int num_reads;
	unsigned int rng_seed;
};

int cancel_threads;

int parse_options(int argc, char *const *argv, struct options *options)
{
	signed char c;

	/* Set defaults here */
	*options = (struct options){
		.test_dir = ".",
		.num_reads = 1000,
		.readers = 10,
		.size = 10,
	};

	/* Load options from command line here */
	while ((c = getopt(argc, argv, "cd:g:n:r:s:t:")) != -1) {
		switch (c) {
		case 'c':
			options->no_cleanup = true;
			break;

		case 'd':
			options->test_dir = optarg;
			break;

		case 'g':
			options->rng_seed = strtol(optarg, NULL, 10);
			break;

		case 'n':
			options->num_reads = strtol(optarg, NULL, 10);
			break;

		case 'r':
			options->readers = strtol(optarg, NULL, 10);
			break;

		case 's':
			options->size = strtol(optarg, NULL, 10);
			break;

		case 't':
			options->timeout = strtol(optarg, NULL, 10);
			break;
		}
	}

	return 0;
}

void *reader(void *data)
{
	struct read_data *read_data = (struct read_data *)data;
	int i;
	int fd = -1;
	void *buffer = malloc(read_data->filesize);

	if (!buffer) {
		err_msg("Failed to alloc read buffer");
		goto out;
	}

	fd = openat(read_data->dir_fd, read_data->filename,
		    O_RDONLY | O_CLOEXEC);
	if (fd == -1) {
		err_msg("Failed to open file");
		goto out;
	}

	for (i = 0; i < read_data->num_reads && !cancel_threads; ++i) {
		off_t offset = rnd(read_data->filesize, &read_data->rng_seed);
		size_t count =
			rnd(read_data->filesize - offset, &read_data->rng_seed);
		ssize_t err = pread(fd, buffer, count, offset);

		if (err != count)
			err_msg("failed to read with value %lu", err);
	}

out:
	close(fd);
	free(read_data);
	free(buffer);
	return NULL;
}

int write_data(int cmd_fd, int dir_fd, const char *name, size_t size)
{
	int fd = openat(dir_fd, name, O_RDWR | O_CLOEXEC);
	struct incfs_permit_fill permit_fill = {
		.file_descriptor = fd,
	};
	int error = 0;
	int i;
	int block_count = 1 + (size - 1) / INCFS_DATA_FILE_BLOCK_SIZE;

	if (fd == -1) {
		err_msg("Could not open file for writing %s", name);
		return -errno;
	}

	if (ioctl(cmd_fd, INCFS_IOC_PERMIT_FILL, &permit_fill)) {
		err_msg("Failed to call PERMIT_FILL");
		error = -errno;
		goto out;
	}

	for (i = 0; i < block_count; ++i) {
		uint8_t data[INCFS_DATA_FILE_BLOCK_SIZE] = {};
		size_t block_size =
			size > i * INCFS_DATA_FILE_BLOCK_SIZE ?
				INCFS_DATA_FILE_BLOCK_SIZE :
				size - (i * INCFS_DATA_FILE_BLOCK_SIZE);
		struct incfs_fill_block fill_block = {
			.compression = COMPRESSION_NONE,
			.block_index = i,
			.data_len = block_size,
			.data = ptr_to_u64(data),
		};
		struct incfs_fill_blocks fill_blocks = {
			.count = 1,
			.fill_blocks = ptr_to_u64(&fill_block),
		};
		int written = ioctl(fd, INCFS_IOC_FILL_BLOCKS, &fill_blocks);

		if (written != 1) {
			error = -errno;
			err_msg("Failed to write block %d in file %s", i, name);
			break;
		}
	}
out:
	close(fd);
	return error;
}

int test_files(int src_dir, int dst_dir, struct options const *options)
{
	unsigned int seed = options->rng_seed;
	int cmd_file = openat(dst_dir, INCFS_PENDING_READS_FILENAME,
			      O_RDONLY | O_CLOEXEC);
	int err;
	const char *name = "001";
	incfs_uuid_t id;
	size_t size;
	int i;
	pthread_t *threads = NULL;

	size = 1 << (rnd(options->size, &seed) + 12);
	size += rnd(size, &seed);

	if (cmd_file == -1) {
		err_msg("Could not open command file");
		return -errno;
	}

	err = emit_file(cmd_file, NULL, name, &id, size, NULL);
	if (err) {
		err_msg("Failed to create file %s", name);
		return err;
	}

	threads = malloc(sizeof(pthread_t) * options->readers);
	if (!threads) {
		err_msg("Could not allocate memory for threads");
		return -ENOMEM;
	}

	for (i = 0; i < options->readers; ++i) {
		struct read_data *read_data = malloc(sizeof(*read_data));

		if (!read_data) {
			err_msg("Failed to allocate read_data");
			err = -ENOMEM;
			break;
		}

		*read_data = (struct read_data){
			.filename = name,
			.dir_fd = dst_dir,
			.filesize = size,
			.num_reads = options->num_reads,
			.rng_seed = seed,
		};

		rnd(0, &seed);

		err = pthread_create(threads + i, 0, reader, read_data);
		if (err) {
			err_msg("Failed to create thread");
			free(read_data);
			break;
		}
	}

	if (err)
		cancel_threads = 1;
	else
		err = write_data(cmd_file, dst_dir, name, size);

	for (; i > 0; --i) {
		if (pthread_join(threads[i - 1], NULL)) {
			err_msg("FATAL: failed to join thread");
			exit(-errno);
		}
	}

	free(threads);
	close(cmd_file);
	return err;
}

int main(int argc, char *const *argv)
{
	struct options options;
	int err;
	const char *src_dir = "src";
	const char *dst_dir = "dst";
	int src_dir_fd = -1;
	int dst_dir_fd = -1;

	err = parse_options(argc, argv, &options);
	if (err)
		return err;

	err = chdir(options.test_dir);
	if (err) {
		err_msg("Failed to change to %s", options.test_dir);
		return -errno;
	}

	err = remove_dir(src_dir) || remove_dir(dst_dir);
	if (err)
		return err;

	err = mkdir(src_dir, 0700);
	if (err) {
		err_msg("Failed to make directory %s", src_dir);
		err = -errno;
		goto cleanup;
	}

	err = mkdir(dst_dir, 0700);
	if (err) {
		err_msg("Failed to make directory %s", src_dir);
		err = -errno;
		goto cleanup;
	}

	err = mount_fs(dst_dir, src_dir, options.timeout);
	if (err) {
		err_msg("Failed to mount incfs");
		goto cleanup;
	}

	src_dir_fd = open(src_dir, O_RDONLY | O_CLOEXEC);
	dst_dir_fd = open(dst_dir, O_RDONLY | O_CLOEXEC);
	if (src_dir_fd == -1 || dst_dir_fd == -1) {
		err_msg("Failed to open src or dst dir");
		err = -errno;
		goto cleanup;
	}

	err = test_files(src_dir_fd, dst_dir_fd, &options);

cleanup:
	close(src_dir_fd);
	close(dst_dir_fd);
	if (!options.no_cleanup) {
		umount(dst_dir);
		remove_dir(dst_dir);
		remove_dir(src_dir);
	}

	return err;
}
