#include	<u.h>
#include	<libc.h>
#include	<ctype.h>
#include	<bio.h>

/*
 * tail command, posix plus v10 option -r.
 * the simple command tail -c, legal in v10, is illegal
 */

long	count;
int	anycount;
int	follow;
int	file	= 0;
char*	umsg	= "usage: tail [-n N] [-c N] [-f] [-r] [+-N[bc][fr]] [file]";

Biobuf	bout;
enum
{
	BEG,
	END
} origin = END;
enum
{
	CHARS,
	LINES
} units = LINES;
enum
{
	FWD,
	REV
} dir = FWD;

extern	void	copy(void);
extern	void	fatal(char*);
extern	int	getnumber(char*);
extern	void	keep(void);
extern	void	reverse(void);
extern	void	skip(void);
extern	void	suffix(char*);
extern	long	tread(char*, long);
#define trunc tailtrunc
extern	void	trunc(Dir*, Dir**);
extern	long	tseek(long, int);
extern	void	twrite(char*, long);
extern	void	usage(void);

#define JUMP(o,p) tseek(o,p), copy()

void
main(int argc, char **argv)
{
	int seekable, c;

	Binit(&bout, 1, OWRITE);
	for(; argc > 1 && ((c=*argv[1])=='-'||c=='+'); argc--,argv++ ) {
		if(getnumber(argv[1])) {
			suffix(argv[1]);
			continue;
		} else
		if(c == '-')
			switch(argv[1][1]) {
			case 'c':
				units = CHARS;
			case 'n':
				if(getnumber(argv[1]+2))
					continue;
				else
				if(argc > 2 && getnumber(argv[2])) {
					argc--, argv++;
					continue;
				} else
					usage();
			case 'r':
				dir = REV;
				continue;
			case 'f':
				follow++;
				continue;
			case '-':
				argc--, argv++;
			}
		break;
	}
	if(dir==REV && (units==CHARS || follow || origin==BEG))
		fatal("incompatible options");
	if(!anycount)
		count = dir==REV? ~0UL>>1: 10;
	if(origin==BEG && units==LINES && count>0)
		count--;
	if(argc > 2)
		usage();
	if(argc > 1 && (file=open(argv[1],0)) < 0)
		fatal(argv[1]);
	seekable = seek(file,0L,0) == 0;

	if(!seekable && origin==END)
		keep();
	else
	if(!seekable && origin==BEG)
		skip();
	else
	if(units==CHARS && origin==END)
		JUMP(-count, 2);
	else
	if(units==CHARS && origin==BEG)
		JUMP(count, 0);
	else
	if(units==LINES && origin==END)
		reverse();
	else
	if(units==LINES && origin==BEG)
		skip();
	if(follow && seekable)
		for(;;) {
			static Dir *sb0, *sb1;
			trunc(sb1, &sb0);
			copy();
			trunc(sb0, &sb1);
			sleep(5000);
		}
	exits(0);
}

void
trunc(Dir *old, Dir **new)
{
	Dir *d;
	ulong olength;

	d = dirfstat(file);
	if(d == nil)
		return;
	olength = 0;
	if(old)
		olength = old->length;
	if(d->length < olength)
		d->length = tseek(0L, 0);
	free(*new);
	*new = d;
}

void
suffix(char *s)
{
	while(*s && strchr("0123456789+-", *s))
		s++;
	switch(*s) {
	case 'b':
		if((count *= 1024) < 0)
			fatal("too big");
	case 'c':
		units = CHARS;
	case 'l':
		s++;
	}
	switch(*s) {
	case 'r':
		dir = REV;
		return;
	case 'f':
		follow++;
		return;
	case 0:
		return;
	}
	usage();
}

/*
 * read past head of the file to find tail
 */
void
skip(void)
{
	int i;
	long n;
	char buf[Bsize];
	if(units == CHARS) {
		for( ; count>0; count -=n) {
			n = count<Bsize? count: Bsize;
			if(!(n = tread(buf, n)))
				return;
		}
	} else /*units == LINES*/ {
		n = i = 0;
		while(count > 0) {
			if(!(n = tread(buf, Bsize)))
				return;
			for(i=0; i<n && count>0; i++)
				if(buf[i]=='\n')
					count--;
		}
		twrite(buf+i, n-i);
	}
	copy();
}

void
copy(void)
{
	long n;
	char buf[Bsize];
	while((n=tread(buf, Bsize)) > 0) {
		twrite(buf, n);
		Bflush(&bout);	/* for FWD on pipe; else harmless */
	}
}

/*
 * read whole file, keeping the tail
 *	complexity is length(file)*length(tail).
 *	could be linear.
 */
void
keep(void)
{
	int len = 0;
	long bufsiz = 0;
	char *buf = 0;
	int j, k, n;

	for(n=1; n;) {
		if(len+Bsize > bufsiz) {
			bufsiz += 2*Bsize;
			if(!(buf = realloc(buf, bufsiz+1)))
				fatal("out of space");
		}
		for(; n && len<bufsiz; len+=n)
			n = tread(buf+len, bufsiz-len);
		if(count >= len)
			continue;
		if(units == CHARS)
			j = len - count;
		else {
			/* units == LINES */
			j = buf[len-1]=='\n'? len-1: len;
			for(k=0; j>0; j--)
				if(buf[j-1] == '\n')
					if(++k >= count)
						break;
		}
		memmove(buf, buf+j, len-=j);
	}
	if(dir == REV) {
		if(len>0 && buf[len-1]!='\n')
			buf[len++] = '\n';
		for(j=len-1 ; j>0; j--)
			if(buf[j-1] == '\n') {
				twrite(buf+j, len-j);
				if(--count <= 0)
					return;
				len = j;
			}
	}
	if(count > 0)
		twrite(buf, len);
}

/*
 * count backward and print tail of file
 */
void
reverse(void)
{
	int first;
	long len = 0;
	long n = 0;
	long bufsiz = 0;
	char *buf = 0;
	long pos = tseek(0L, 2);

	for(first=1; pos>0 && count>0; first=0) {
		n = pos>Bsize? Bsize: (int)pos;
		pos -= n;
		if(len+n > bufsiz) {
			bufsiz += 2*Bsize;
			if(!(buf = realloc(buf, bufsiz+1)))
				fatal("out of space");
		}
		memmove(buf+n, buf, len);
		len += n;
		tseek(pos, 0);
		if(tread(buf, n) != n)
			fatal("length error");
		if(first && buf[len-1]!='\n')
			buf[len++] = '\n';
		for(n=len-1 ; n>0 && count>0; n--)
			if(buf[n-1] == '\n') {
				count--;
				if(dir == REV)
					twrite(buf+n, len-n);
				len = n;
			}
	}
	if(dir == FWD) {
		tseek(n==0? 0 : pos+n+1, 0);
		copy();
	} else
	if(count > 0)
		twrite(buf, len);
}

long
tseek(long o, int p)
{
	o = seek(file, o, p);
	if(o == -1)
		fatal("");
	return o;
}

long
tread(char *buf, long n)
{
	int r = read(file, buf, n);
	if(r == -1)
		fatal("");
	return r;
}

void
twrite(char *s, long n)
{
	if(Bwrite(&bout, s, n) != n)
		fatal("");
}

int
getnumber(char *s)
{
	if(*s=='-' || *s=='+')
		s++;
	if(!isdigit(*s))
		return 0;
	if(s[-1] == '+')
		origin = BEG;
	if(anycount++)
		fatal("excess option");
	count = atol(s);

	/* check range of count */
	if(count < 0 ||	(int)count != count)
		fatal("too big");
	return 1;
}	

void		
fatal(char *s)
{
	char buf[ERRMAX];

	errstr(buf, sizeof buf);
	fprint(2, "tail: %s: %s\n", s, buf);
	exits(s);
}

void
usage(void)
{
	fprint(2, "%s\n", umsg);
	exits("usage");
}
