#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>

#include "fio.h"

static int root_warn;

static int extend_file(struct thread_data *td, struct fio_file *f)
{
	int r, new_layout = 0, unlink_file = 0, flags;
	unsigned long long left;
	unsigned int bs;
	char *b;

	/*
	 * check if we need to lay the file out complete again. fio
	 * does that for operations involving reads, or for writes
	 * where overwrite is set
	 */
	if (td_read(td) || (td_write(td) && td->o.overwrite))
		new_layout = 1;
	if (td_write(td) && !td->o.overwrite)
		unlink_file = 1;

	if ((unlink_file || new_layout) && (f->flags & FIO_FILE_EXISTS)) {
		if (unlink(f->file_name) < 0) {
			td_verror(td, errno, "unlink");
			return 1;
		}
	}

	flags = O_WRONLY | O_CREAT;
	if (new_layout)
		flags |= O_TRUNC;

	f->fd = open(f->file_name, flags, 0644);
	if (f->fd < 0) {
		td_verror(td, errno, "open");
		return 1;
	}

	if (ftruncate(f->fd, f->real_file_size) == -1) {
		td_verror(td, errno, "ftruncate");
		goto err;
	}

	if (!new_layout)
		goto done;

	if (posix_fallocate(f->fd, 0, f->real_file_size) < 0) {
		td_verror(td, errno, "posix_fallocate");
		goto err;
	}

	b = malloc(td->o.max_bs[DDIR_WRITE]);
	memset(b, 0, td->o.max_bs[DDIR_WRITE]);

	left = f->real_file_size;
	while (left && !td->terminate) {
		bs = td->o.max_bs[DDIR_WRITE];
		if (bs > left)
			bs = left;

		r = write(f->fd, b, bs);

		if (r == (int) bs) {
			left -= bs;
			continue;
		} else {
			if (r < 0)
				td_verror(td, errno, "write");
			else
				td_verror(td, EIO, "write");

			break;
		}
	}

	if (td->terminate)
		unlink(f->file_name);
	else if (td->o.create_fsync)
		fsync(f->fd);

	free(b);
done:
	close(f->fd);
	f->fd = -1;
	return 0;
err:
	close(f->fd);
	f->fd = -1;
	return 1;
}

static unsigned long long get_rand_file_size(struct thread_data *td)
{
	unsigned long long ret;
	long r;

	r = os_random_long(&td->file_size_state);
	ret = td->o.file_size_low + (unsigned long long) ((double) (td->o.file_size_high - td->o.file_size_low) * (r / (RAND_MAX + 1.0)));
	ret -= (ret % td->o.rw_min_bs);
	return ret;
}

static int file_size(struct thread_data *td, struct fio_file *f)
{
	struct stat st;

	if (fstat(f->fd, &st) == -1) {
		td_verror(td, errno, "fstat");
		return 1;
	}

	f->real_file_size = st.st_size;
	return 0;
}

static int bdev_size(struct thread_data *td, struct fio_file *f)
{
	unsigned long long bytes;
	int r;

	r = blockdev_size(f->fd, &bytes);
	if (r) {
		td_verror(td, r, "blockdev_size");
		return 1;
	}

	f->real_file_size = bytes;
	return 0;
}

static int get_file_size(struct thread_data *td, struct fio_file *f)
{
	int ret = 0;

	if (f->flags & FIO_SIZE_KNOWN)
		return 0;

	if (f->filetype == FIO_TYPE_FILE)
		ret = file_size(td, f);
	else if (f->filetype == FIO_TYPE_BD)
		ret = bdev_size(td, f);
	else
		f->real_file_size = -1;

	if (ret)
		return ret;

	if (f->file_offset > f->real_file_size) {
		log_err("%s: offset extends end (%Lu > %Lu)\n", td->o.name, f->file_offset, f->real_file_size);
		return 1;
	}

	f->flags |= FIO_SIZE_KNOWN;
	return 0;
}

int file_invalidate_cache(struct thread_data *td, struct fio_file *f)
{
	int ret = 0;

	if (td->o.odirect)
		return 0;

	/*
	 * FIXME: add blockdev flushing too
	 */
	if (f->mmap)
		ret = madvise(f->mmap, f->io_size, MADV_DONTNEED);
	else if (f->filetype == FIO_TYPE_FILE)
		ret = fadvise(f->fd, f->file_offset, f->io_size, POSIX_FADV_DONTNEED);
	else if (f->filetype == FIO_TYPE_BD) {
		ret = blockdev_invalidate_cache(f->fd);
		if (ret < 0 && errno == EACCES && geteuid()) {
			if (!root_warn) {
				log_err("fio: only root may flush block devices. Cache flush bypassed!\n");
				root_warn = 1;
			}
			ret = 0;
		}
	} else if (f->filetype == FIO_TYPE_CHAR || f->filetype == FIO_TYPE_PIPE)
		ret = 0;

	if (ret < 0) {
		td_verror(td, errno, "invalidate_cache");
		return 1;
	}

	return ret;
}

void generic_close_file(struct thread_data fio_unused *td, struct fio_file *f)
{
	close(f->fd);
	f->fd = -1;
}

int generic_open_file(struct thread_data *td, struct fio_file *f)
{
	int is_std = 0;
	int flags = 0;

	if (!strcmp(f->file_name, "-")) {
		if (td_rw(td)) {
			log_err("fio: can't read/write to stdin/out\n");
			return 1;
		}
		is_std = 1;

		/*
		 * move output logging to stderr, if we are writing to stdout
		 */
		if (td_write(td))
			f_out = stderr;
	}

	if (td->o.odirect)
		flags |= OS_O_DIRECT;
	if (td->o.sync_io)
		flags |= O_SYNC;

	if (td_write(td)) {
		flags |= O_RDWR;

		if (f->filetype == FIO_TYPE_FILE)
			flags |= O_CREAT;

		if (is_std)
			f->fd = dup(STDOUT_FILENO);
		else
			f->fd = open(f->file_name, flags, 0600);
	} else {
		if (f->filetype == FIO_TYPE_CHAR)
			flags |= O_RDWR;
		else
			flags |= O_RDONLY;

		if (is_std)
			f->fd = dup(STDIN_FILENO);
		else
			f->fd = open(f->file_name, flags);
	}

	if (f->fd == -1) {
		char buf[FIO_VERROR_SIZE];
		int __e = errno;

		snprintf(buf, sizeof(buf) - 1, "open(%s)", f->file_name);

		td_verror(td, __e, buf);
	}

	if (get_file_size(td, f))
		goto err;

	return 0;
err:
	close(f->fd);
	return 1;
}

int open_files(struct thread_data *td)
{
	struct fio_file *f;
	unsigned int i;
	int err = 0;

	for_each_file(td, f, i) {
		err = td_io_open_file(td, f);
		if (err) {
			if (td->error == EMFILE) {
				log_err("fio: limited open files to: %d\n", td->nr_open_files);
				td->o.open_files = td->nr_open_files;
				err = 0;
				clear_error(td);
			}
			break;
		}

		if (td->o.open_files == td->nr_open_files)
			break;
	}

	if (!err)
		return 0;

	for_each_file(td, f, i)
		td_io_close_file(td, f);

	return err;
}

/*
 * open/close all files, so that ->real_file_size gets set
 */
static int get_file_sizes(struct thread_data *td)
{
	struct fio_file *f;
	unsigned int i;
	int err = 0;

	for_each_file(td, f, i) {
		if (td->io_ops->open_file(td, f)) {
			if (td->error != ENOENT) {
				log_err("%s\n", td->verror);
				err = 1;
			}
			clear_error(td);
		} else {
			if (td->io_ops->close_file)
				td->io_ops->close_file(td, f);
		}

		if (f->real_file_size == -1ULL && td->o.size)
			f->real_file_size = td->o.size / td->o.nr_files;
	}

	return err;
}

/*
 * Open the files and setup files sizes, creating files if necessary.
 */
int setup_files(struct thread_data *td)
{
	unsigned long long total_size, extend_size;
	struct fio_file *f;
	unsigned int i;
	int err = 0, need_extend;

	/*
	 * if ioengine defines a setup() method, it's responsible for
	 * opening the files and setting f->real_file_size to indicate
	 * the valid range for that file.
	 */
	if (td->io_ops->setup)
		err = td->io_ops->setup(td);
	else
		err = get_file_sizes(td);

	if (err)
		return err;

	/*
	 * check sizes. if the files/devices do not exist and the size
	 * isn't passed to fio, abort.
	 */
	total_size = 0;
	for_each_file(td, f, i) {
		if (f->real_file_size == -1ULL)
			total_size = -1ULL;
		else
			total_size += f->real_file_size;
	}

	/*
	 * device/file sizes are zero and no size given, punt
	 */
	if ((!total_size || total_size == -1ULL) && !td->o.size) {
		log_err("%s: you need to specify size=\n", td->o.name);
		td_verror(td, EINVAL, "total_file_size");
		return 1;
	}

	/*
	 * now file sizes are known, so we can set ->io_size. if size= is
	 * not given, ->io_size is just equal to ->real_file_size. if size
	 * is given, ->io_size is size / nr_files.
	 */
	extend_size = total_size = 0;
	need_extend = 0;
	for_each_file(td, f, i) {
		f->file_offset = td->o.start_offset;

		if (!td->o.file_size_low) {
			/*
			 * no file size range given, file size is equal to
			 * total size divided by number of files. if that is
			 * zero, set it to the real file size.
			 */
			f->io_size = td->o.size / td->o.nr_files;
			if (!f->io_size) {
				if (f->file_offset > f->real_file_size)
					goto err_offset;
				f->io_size = f->real_file_size - f->file_offset;
			}
		} else if (f->real_file_size < td->o.file_size_low ||
			   f->real_file_size > td->o.file_size_high) {
			if (f->file_offset > td->o.file_size_low) 
				goto err_offset;
			/*
			 * file size given. if it's fixed, use that. if it's a
			 * range, generate a random size in-between.
			 */
			if (td->o.file_size_low == td->o.file_size_high)
				f->io_size = td->o.file_size_low - f->file_offset;
			else
				f->io_size = get_rand_file_size(td) - f->file_offset;
		} else if (f->file_offset > f->real_file_size)
			goto err_offset;
		else
			f->io_size = f->real_file_size - f->file_offset;

		if (f->io_size == -1ULL)
			total_size = -1ULL;
		else
			total_size += f->io_size;

		if (f->filetype == FIO_TYPE_FILE &&
		    (f->io_size + f->file_offset) > f->real_file_size &&
		    !(td->io_ops->flags & FIO_DISKLESSIO)) {
			need_extend++;
			extend_size += (f->io_size + f->file_offset);
			f->flags |= FIO_FILE_EXTEND;
		}	
	}

	if (!td->o.size || td->o.size > total_size)
		td->o.size = total_size;

	/*
	 * See if we need to extend some files
	 */
	if (need_extend) {
		temp_stall_ts = 1;
		log_info("%s: Laying out IO file(s) (%u files / %LuMiB)\n",
			td->o.name, need_extend, extend_size >> 20);

		for_each_file(td, f, i) {
			if (!(f->flags & FIO_FILE_EXTEND))
				continue;

			assert(f->filetype == FIO_TYPE_FILE);
			f->flags &= ~FIO_FILE_EXTEND;
			f->real_file_size = (f->io_size + f->file_offset);
			err = extend_file(td, f);
			if (err)
				break;
		}
		temp_stall_ts = 0;
	}

	if (err)
		return err;

	if (!td->o.zone_size)
		td->o.zone_size = td->o.size;

	td->total_io_size = td->o.size * td->o.loops;
	return 0;
err_offset:
	log_err("%s: you need to specify valid offset=\n", td->o.name);
	return 1;
}

int init_random_map(struct thread_data *td)
{
	int num_maps, blocks;
	struct fio_file *f;
	unsigned int i;

	if (td->o.norandommap)
		return 0;

	for_each_file(td, f, i) {
		blocks = (f->real_file_size + td->o.rw_min_bs - 1) / td->o.rw_min_bs;
		num_maps = (blocks + BLOCKS_PER_MAP-1)/ BLOCKS_PER_MAP;
		f->file_map = malloc(num_maps * sizeof(long));
		if (!f->file_map) {
			log_err("fio: failed allocating random map. If running a large number of jobs, try the 'norandommap' option\n");
			return 1;
		}
		f->num_maps = num_maps;
		memset(f->file_map, 0, num_maps * sizeof(long));
	}

	return 0;
}

void close_files(struct thread_data *td)
{
	struct fio_file *f;
	unsigned int i;

	for_each_file(td, f, i) {
		if (td->o.unlink && f->filetype == FIO_TYPE_FILE)
			unlink(f->file_name);

		td_io_close_file(td, f);

		free(f->file_name);
		f->file_name = NULL;

		if (f->file_map) {
			free(f->file_map);
			f->file_map = NULL;
		}
	}

	td->o.filename = NULL;
	free(td->files);
	td->files = NULL;
	td->o.nr_files = 0;
}

static void get_file_type(struct fio_file *f)
{
	struct stat sb;

	if (!strcmp(f->file_name, "-"))
		f->filetype = FIO_TYPE_PIPE;
	else
		f->filetype = FIO_TYPE_FILE;

	if (!lstat(f->file_name, &sb)) {
		if (S_ISBLK(sb.st_mode))
			f->filetype = FIO_TYPE_BD;
		else if (S_ISCHR(sb.st_mode))
			f->filetype = FIO_TYPE_CHAR;
		else if (S_ISFIFO(sb.st_mode))
			f->filetype = FIO_TYPE_PIPE;
	}
}

int add_file(struct thread_data *td, const char *fname)
{
	int cur_files = td->files_index;
	char file_name[PATH_MAX];
	struct fio_file *f;
	int len = 0;

	td->files = realloc(td->files, (cur_files + 1) * sizeof(*f));

	f = &td->files[cur_files];
	memset(f, 0, sizeof(*f));
	f->fd = -1;

	/*
	 * init function, io engine may not be loaded yet
	 */
	if (td->io_ops && (td->io_ops->flags & FIO_DISKLESSIO))
		f->real_file_size = -1ULL;

	if (td->o.directory)
		len = sprintf(file_name, "%s/", td->o.directory);

	sprintf(file_name + len, "%s", fname);
	f->file_name = strdup(file_name);

	get_file_type(f);

	td->files_index++;
	if (f->filetype == FIO_TYPE_FILE)
		td->nr_normal_files++;

	return cur_files;
}

void get_file(struct fio_file *f)
{
	assert(f->flags & FIO_FILE_OPEN);
	f->references++;
}

void put_file(struct thread_data *td, struct fio_file *f)
{
	if (!(f->flags & FIO_FILE_OPEN))
		return;

	assert(f->references);
	if (--f->references)
		return;

	if (should_fsync(td) && td->o.fsync_on_close)
		fsync(f->fd);

	if (td->io_ops->close_file)
		td->io_ops->close_file(td, f);

	td->nr_open_files--;
	f->flags &= ~FIO_FILE_OPEN;
}

static int recurse_dir(struct thread_data *td, const char *dirname)
{
	struct dirent *dir;
	int ret = 0;
	DIR *D;

	D = opendir(dirname);
	if (!D) {
		char buf[FIO_VERROR_SIZE];

		snprintf(buf, FIO_VERROR_SIZE - 1, "opendir(%s)", dirname);
		td_verror(td, errno, buf);
		return 1;
	}

	while ((dir = readdir(D)) != NULL) {
		char full_path[PATH_MAX];
		struct stat sb;

		if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, ".."))
			continue;

		sprintf(full_path, "%s/%s", dirname, dir->d_name);

		if (lstat(full_path, &sb) == -1) {
			if (errno != ENOENT) {
				td_verror(td, errno, "stat");
				return 1;
			}
		}

		if (S_ISREG(sb.st_mode)) {
			add_file(td, full_path);
			td->o.nr_files++;
			continue;
		}
		if (!S_ISDIR(sb.st_mode))
			continue;

		if ((ret = recurse_dir(td, full_path)) != 0)
			break;
	}

	closedir(D);
	return ret;
}

int add_dir_files(struct thread_data *td, const char *path)
{
	int ret = recurse_dir(td, path);

	if (!ret)
		log_info("fio: opendir added %d files\n", td->o.nr_files);

	return ret;
}

void dup_files(struct thread_data *td, struct thread_data *org)
{
	struct fio_file *f;
	unsigned int i;
	size_t bytes;

	if (!org->files)
		return;

	bytes = org->files_index * sizeof(*f);
	td->files = malloc(bytes);
	memcpy(td->files, org->files, bytes);

	for_each_file(td, f, i) {
		if (f->file_name)
			f->file_name = strdup(f->file_name);
	}
}

/*
 * Returns the index that matches the filename, or -1 if not there
 */
int get_fileno(struct thread_data *td, const char *fname)
{
	struct fio_file *f;
	unsigned int i;

	for_each_file(td, f, i)
		if (!strcmp(f->file_name, fname))
			return i;

	return -1;
}

/*
 * For log usage, where we add/open/close files automatically
 */
void free_release_files(struct thread_data *td)
{
	close_files(td);
	td->files_index = 0;
	td->nr_normal_files = 0;
}
