/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#include "../file_common.h"
#include <libgen.h>
#include <string.h>
#include <inttypes.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>

static unsigned char bigbuffer[BIGBUFFERSIZE];

/*
 * Writes (or appends) a given value to a file repeatedly.
 * See header file for defaults.
 */

static void usage(char *);

/*
 * pseudo-randomize the buffer
 */
static void randomize_buffer(int block_size) {
	int i;
	char rnd = rand() & 0xff;
	for (i = 0; i < block_size; i++)
		bigbuffer[i] ^= rnd;
}

int
main(int argc, char **argv)
{
	int		bigfd;
	int		c;
	int		oflag = 0;
	int		err = 0;
	int		k;
	long		i;
	int64_t		good_writes = 0;
	uchar_t		nxtfillchar;
	char		*prog = argv[0];
	/*
	 * Default Parameters
	 */
	int		write_count = BIGFILESIZE;
	uchar_t		fillchar = DATA;
	int		block_size = BLOCKSZ;
	char		*filename = NULL;
	char		*operation = NULL;
	offset_t	noffset, offset = 0;
	int		verbose = 0;
	int		rsync = 0;
	int		wsync = 0;

	/*
	 * Process Arguments
	 */
	while ((c = getopt(argc, argv, "b:c:d:s:f:o:vwr")) != -1) {
		switch (c) {
			case 'b':
				block_size = atoi(optarg);
				break;
			case 'c':
				write_count = atoi(optarg);
				break;
			case 'd':
				if (optarg[0] == 'R')
					fillchar = 'R'; /* R = random data */
				else
					fillchar = atoi(optarg);
				break;
			case 's':
				offset = atoll(optarg);
				break;
			case 'f':
				filename = optarg;
				break;
			case 'o':
				operation = optarg;
				break;
			case 'v':
				verbose = 1;
				break;
			case 'w':
				wsync = 1;
				break;
			case 'r':
				rsync = 1;
				break;
			case '?':
				(void) printf("unknown arg %c\n", optopt);
				usage(prog);
				break;
		}
	}

	/*
	 * Validate Parameters
	 */
	if (!filename) {
		(void) printf("Filename not specified (-f <file>)\n");
		err++;
	}

	if (!operation) {
		(void) printf("Operation not specified (-o <operation>).\n");
		err++;
	}

	if (block_size > BIGBUFFERSIZE) {
		(void) printf("block_size is too large max==%d.\n",
		    BIGBUFFERSIZE);
		err++;
	}

	if (err) {
		usage(prog); /* no return */
		return (1);
	}

	/*
	 * Prepare the buffer and determine the requested operation
	 */
	nxtfillchar = fillchar;
	k = 0;

	if (fillchar == 'R')
		srand(time(NULL));

	for (i = 0; i < block_size; i++) {
		bigbuffer[i] = nxtfillchar;

		if (fillchar == 0) {
			if ((k % DATA_RANGE) == 0) {
				k = 0;
			}
			nxtfillchar = k++;
		} else if (fillchar == 'R') {
			nxtfillchar = rand() & 0xff;
		}
	}

	/*
	 * using the strncmp of operation will make the operation match the
	 * first shortest match - as the operations are unique from the first
	 * character this means that we match single character operations
	 */
	if ((strncmp(operation, "create", strlen(operation) + 1)) == 0 ||
	    (strncmp(operation, "overwrite", strlen(operation) + 1)) == 0) {
		oflag = (O_RDWR|O_CREAT);
	} else if ((strncmp(operation, "append", strlen(operation) + 1)) == 0) {
		oflag = (O_RDWR|O_APPEND);
	} else {
		(void) printf("valid operations are <create|append> not '%s'\n",
		    operation);
		usage(prog);
	}

	if (rsync) {
		oflag = oflag | O_RSYNC;
	}

	if (wsync) {
		oflag = oflag | O_SYNC;
	}

	/*
	 * Given an operation (create/overwrite/append), open the file
	 * accordingly and perform a write of the appropriate type.
	 */
	if ((bigfd = open(filename, oflag, 0666)) == -1) {
		(void) printf("open %s: failed [%s]%d. Aborting!\n", filename,
		    strerror(errno), errno);
		exit(errno);
	}
	noffset = lseek64(bigfd, offset, SEEK_SET);
	if (noffset != offset) {
		(void) printf("llseek %s (%lld/%lld) failed [%s]%d.Aborting!\n",
		    filename, offset, noffset, strerror(errno), errno);
		exit(errno);
	}

	if (verbose) {
		(void) printf("%s: block_size = %d, write_count = %d, "
		    "offset = %lld, ", filename, block_size,
		    write_count, offset);
		if (fillchar == 'R') {
			(void) printf("data = [random]\n");
		} else {
			(void) printf("data = %s%d\n",
			    (fillchar == 0) ? "0->" : "",
			    (fillchar == 0) ? DATA_RANGE : fillchar);
		}
	}

	for (i = 0; i < write_count; i++) {
		ssize_t n;
		if (fillchar == 'R')
			randomize_buffer(block_size);

		if ((n = write(bigfd, &bigbuffer, block_size)) == -1) {
			(void) printf("write failed (%ld), good_writes = %"
			    PRId64 ", " "error: %s[%d]\n",
			    (long)n, good_writes,
			    strerror(errno),
			    errno);
			exit(errno);
		}
		good_writes++;
	}

	if (verbose) {
		(void) printf("Success: good_writes = %" PRId64 "(%"
		    PRId64 ")\n", good_writes, (good_writes * block_size));
	}

	return (0);
}

static void
usage(char *prog)
{
	(void) printf("Usage: %s [-v] -o {create,overwrite,append} -f file_name"
	    " [-b block_size]\n"
	    "\t[-s offset] [-c write_count] [-d data]\n\n"
	    "Where [data] equal to zero causes chars "
	    "0->%d to be repeated throughout, or [data]\n"
	    "equal to 'R' for pseudorandom data.\n",
	    prog, DATA_RANGE);

	exit(1);
}
