/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include "ioshark.h"
#include "ioshark_bench.h"

/*
 * The purpose of this code is to convert mmap() calls into
 * a mix of (semi)-random reads and writes.
 * PROT_READ => 4KB/8KB/16KB random reads.
 * PROT_WRITE => adds 4KB random writes.
 */

extern char *progname;

#define IOSHARK_MAX_MMAP_IOLEN	(16*1024)

#define MMAP_ENTS		16

struct mmap_io_ent_tab_s {
	off_t offset;
	size_t len;
};

struct mmap_io_ent_s {
	int				num_entries;
	struct mmap_io_ent_tab_s	table[MMAP_ENTS + 1];
	size_t				resid;
};

static void
setup_mmap_io_state(struct mmap_io_ent_s *mio,
		    size_t total_len, off_t offset)
{
	int slice;

	memset(mio, 0, sizeof(struct mmap_io_ent_s));
	mio->resid = total_len;
	slice = MAX(IOSHARK_MAX_MMAP_IOLEN,
		    total_len / MMAP_ENTS);
	while (total_len > 0) {
		assert(mio->num_entries < MMAP_ENTS + 1);
		mio->table[mio->num_entries].offset = offset;
		mio->table[mio->num_entries].len =
			MIN((u_int64_t)total_len, (u_int64_t)slice);
		total_len -= mio->table[mio->num_entries].len;
		offset += mio->table[mio->num_entries].len;
		mio->num_entries++;
	}
}

static size_t
mmap_getnext_off_len(struct mmap_io_ent_s *mio,
		     off_t *offset)
{
	int i;
	int find_rand_index[MMAP_ENTS + 1];
	int rand_index_len = 0;
	size_t iolength;

	if (mio->resid == 0)
		return 0;
	/* Pick a slot with residual length > 0 at random first */
	for (i = 0 ; i < MMAP_ENTS + 1 ; i++) {
		if (mio->table[i].len > 0)
			find_rand_index[rand_index_len++] = i;
	}
	i = find_rand_index[rand() % rand_index_len];
	/* Randomize iolength 4K-16K */
	iolength = ((rand() % 4) + 1) * 4096;
	iolength = MIN(mio->table[i].len, iolength);
	*offset = mio->table[i].offset;
	mio->table[i].offset += iolength;
	mio->table[i].len -= iolength;
	mio->resid -= iolength;
	return iolength;
}

static void
mmap_do_io(void *db_node, int prot, off_t offset, size_t len,
	   char **bufp, int *buflen, u_int64_t *op_counts,
	   struct rw_bytes_s *rw_bytes)
{
	char *p;
	int ret;

	if (!(prot & IOSHARK_PROT_WRITE)) {
		/* Only preads */
		p = get_buf(bufp, buflen, len, 0);
		ret = pread(files_db_get_fd(db_node),
			    p, len, offset);
		rw_bytes->bytes_read += len;
		if (ret < 0) {
			fprintf(stderr,
				"%s: mapped pread(%s %zu %lu) error fd=%d %s\n",
				progname, files_db_get_filename(db_node),
				len, offset, files_db_get_fd(db_node),
				strerror(errno));
			exit(EXIT_FAILURE);
		}
		op_counts[IOSHARK_MAPPED_PREAD]++;
	} else {
		/* 50-50 R/W */
		if ((rand() % 2) == 1) {
			p = get_buf(bufp, buflen, len, 1);
			ret = pwrite(files_db_get_fd(db_node),
				     p, len, offset);
			rw_bytes->bytes_written += len;
			if (ret < 0) {
#if 0
				fprintf(stderr,
					"%s: mapped pwrite failed, file unwriteable ? open_flags=%x\n",
					progname,
					fcntl(files_db_get_fd(db_node), F_GETFL));
				exit(EXIT_FAILURE);
#endif
			} else
				op_counts[IOSHARK_MAPPED_PWRITE]++;
		} else {
			p = get_buf(bufp, buflen, len, 0);
			ret = pread(files_db_get_fd(db_node),
				    p, len, offset);
			rw_bytes->bytes_read += len;
			if (ret < 0) {
				fprintf(stderr,
				"%s: mapped pread(%s %zu %lu) error fd=%d %s\n",
					progname, files_db_get_filename(db_node),
					len,
					offset, files_db_get_fd(db_node),
					strerror(errno));
				exit(EXIT_FAILURE);
			}
			op_counts[IOSHARK_MAPPED_PREAD]++;
		}
	}
}

void
ioshark_handle_mmap(void *db_node,
		    struct ioshark_file_operation *file_op,
		    char **bufp, int *buflen, u_int64_t *op_counts,
		    struct rw_bytes_s *rw_bytes)
{
	off_t offset = file_op->mmap_offset;
	size_t len = file_op->mmap_len;
	int prot = file_op->mmap_prot;
	struct mmap_io_ent_s mio;
	struct stat statbuf;

	if (fstat(files_db_get_fd(db_node), &statbuf) < 0) {
		fprintf(stderr,
			"%s: fstat failure %s\n",
			__func__, strerror(errno));
		exit(EXIT_FAILURE);
	}
	/*
	 * The size of the file better accomodate offset + len
	 * Else there is an issue with pre-creation
	 */
	assert(offset + len <= statbuf.st_size);
	if (len <= IOSHARK_MAX_MMAP_IOLEN) {
		mmap_do_io(db_node, prot, offset, len,
			   bufp, buflen, op_counts,
			   rw_bytes);
		return;
	}
	setup_mmap_io_state(&mio, len, offset);
	assert(mio.num_entries > 0);
	while ((len = mmap_getnext_off_len(&mio, &offset))) {
		assert((offset + len) <=
		       (file_op->mmap_offset + file_op->mmap_len));
		mmap_do_io(db_node, prot, offset, len, bufp, buflen,
			   op_counts, rw_bytes);
	}
}
