/*
 * Copyright (c) 2013 SGI
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <xfs/xfs.h>
#include <xfs/command.h>
#include <xfs/input.h>
#include <sys/types.h>
#include <unistd.h>
#include "init.h"
#include "io.h"

static cmdinfo_t seek_cmd;

static void
seek_help(void)
{
	printf(_(
"\n"
" returns the next hole and/or data offset at or after the requested offset\n"
"\n"
" Example:\n"
" 'seek -d 512'		- offset of data at or following offset 512\n"
" 'seek -a -r 0'	- offsets of all data and hole in entire file\n"
"\n"
" Returns the offset of the next data and/or hole. There is an implied hole\n"
" at the end of file. If the specified offset is past end of file, or there\n"
" is no data past the specified offset, EOF is returned.\n"
" -a	-- return the next data and hole starting at the specified offset.\n"
" -d	-- return the next data starting at the specified offset.\n"
" -h	-- return the next hole starting at the specified offset.\n"
" -r	-- return all remaining type(s) starting at the specified offset.\n"
" -s	-- also print the starting offset.\n"
"\n"));
}

#ifndef HAVE_SEEK_DATA
#define	SEEK_DATA	3	/* seek to the next data */
#define	SEEK_HOLE	4	/* seek to the next hole */
#endif

/* values for flag variable */
#define	SEEK_DFLAG	(1 << 0)
#define	SEEK_HFLAG	(1 << 1)
#define	SEEK_RFLAG	(1 << 2)

/* indexes into the seekinfo array */
#define	DATA		0
#define	HOLE		1

struct seekinfo {
	char		*name;		/* display item name */
	int		seektype;	/* data or hole */
	int		mask;		/* compared for print and looping */
} seekinfo[] = {
		{"DATA", SEEK_DATA, SEEK_DFLAG},
		{"HOLE", SEEK_HOLE, SEEK_HFLAG}
};

/* print item type and offset. catch special cases of eof and error */
void
seek_output(
	int	startflag,
	char	*type,
	off64_t	start,
	off64_t	offset)
{
	if (offset == -1) {
		if (errno == ENXIO) {
			if (startflag)
				printf("%s	%lld	EOF\n", type,
					 (long long)start);
			else
				printf("%s	EOF\n", type);
		} else {
			printf("ERR	%lld	", (long long)start);
			fflush(stdout);	/* so the printf preceded the perror */
			perror("");
		}
	} else {
		if (startflag)
			printf("%s	%lld	%lld\n", type,
				(long long)start, (long long)offset);
		else
			printf("%s	%lld\n", type, (long long)offset);
	}
}

static int
seek_f(
	int	argc,
	char	**argv)
{
	off64_t		offset, start;
	size_t		fsblocksize, fssectsize;
	int		c;
	int		current;	/* specify data or hole */
	int		flag;
	int		startflag;

	flag = startflag = 0;
	init_cvtnum(&fsblocksize, &fssectsize);

	while ((c = getopt(argc, argv, "adhrs")) != EOF) {
		switch (c) {
		case 'a':
			flag |= (SEEK_HFLAG | SEEK_DFLAG);
			break;
		case 'd':
			flag |= SEEK_DFLAG;
			break;
		case 'h':
			flag |= SEEK_HFLAG;
			break;
		case 'r':
			flag |= SEEK_RFLAG;
			break;
		case 's':
			startflag = 1;
			break;
		default:
			return command_usage(&seek_cmd);
		}
	}
	if (!(flag & (SEEK_DFLAG | SEEK_HFLAG)) || optind != argc - 1)
		return command_usage(&seek_cmd);

	start = offset = cvtnum(fsblocksize, fssectsize, argv[optind]);
	if (offset < 0)
		return command_usage(&seek_cmd);

	/*
	 * check to see if the offset is a data or hole entry and
	 * decide if we want to display that type of entry.
	 */
	if (flag & SEEK_HFLAG) {
		offset = lseek64(file->fd, start, SEEK_HOLE);
		if ((start == offset) || !(flag & SEEK_DFLAG)) {
			/*
			 * this offset is a hole or are only displaying holes.
			 * if this offset is for data and we are displaying
			 * data, then we will fall through below to
			 * initialize the data search.
			 */
			current = HOLE;
			goto found_hole;
		}
	}

	/* The offset is not a hole, or we are looking just for data */
	current = DATA;
	offset = lseek64(file->fd, start, SEEK_DATA);

found_hole:
	/*
	 * At this point we know which type and the offset of the starting
	 * item. "current" alternates between data / hole entries in
	 * assending order - this alternation is needed even if only one
	 * type is to be displayed.
	 *
	 * An error or EOF will terminate the display, otherwise "flag"
	 * determines if there are more items to be displayed.
	 */
	if (startflag)
		printf("Whence	Start	Result\n");
	else
		printf("Whence	Result\n");

	for (c = 0; flag; c++) {
		if (offset == -1) {
			/* print error or eof if the only entry */
			if (errno != ENXIO || c == 0 )
				seek_output(startflag, seekinfo[current].name,
					    start, offset);
			return 0;	/* stop on error or EOF */
		}

		if (flag & seekinfo[current].mask)
			seek_output(startflag, seekinfo[current].name, start,
				    offset);

		/*
		 * When displaying only a single data and/or hole item, mask
		 * off the item as it is displayed. The loop will end when all
		 * requested items have been displayed.
		 */
		if (!(flag & SEEK_RFLAG))
			flag &= ~seekinfo[current].mask;

		current ^= 1;		/* alternate between data and hole */
		start = offset;
		offset = lseek64(file->fd, start, seekinfo[current].seektype);
	}
	return 0;
}

void
seek_init(void)
{
	seek_cmd.name = "seek";
	seek_cmd.cfunc = seek_f;
	seek_cmd.argmin = 2;
	seek_cmd.argmax = 5;
	seek_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
	seek_cmd.args = _("-a | -d | -h [-r] off");
	seek_cmd.oneline = _("locate the next data and/or hole");
	seek_cmd.help = seek_help;

	add_command(&seek_cmd);
}
