/*
 * interactive diff, inspired/stolen from
 * kernighan and pike, _unix programming environment_.
 */

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

#define opentemp idiffopentemp

int diffbflag;
int diffwflag;

void copy(Biobuf*, char*, Biobuf*, char*);
void idiff(Biobuf*, char*, Biobuf*, char*, Biobuf*, char*, Biobuf*, char*);
int opentemp(char*, int, long);
void rundiff(char*, char*, int);

void
usage(void)
{
	fprint(2, "usage: idiff [-bw] file1 file2\n");
	exits("usage");
}

void
main(int argc, char **argv)
{
	int fd, ofd;
	char diffout[40], idiffout[40];
	Biobuf *b1, *b2, bdiff, bout, bstdout;
	Dir *d;

	ARGBEGIN{
	default:
		usage();
	case 'b':
		diffbflag++;
		break;
	case 'w':
		diffwflag++;
		break;
	}ARGEND

	if(argc != 2)
		usage();

	if((d = dirstat(argv[0])) == nil)
		sysfatal("stat %s: %r", argv[0]);
	if(d->mode&DMDIR)
		sysfatal("%s is a directory", argv[0]);
	free(d);
	if((d = dirstat(argv[1])) == nil)
		sysfatal("stat %s: %r", argv[1]);
	if(d->mode&DMDIR)
		sysfatal("%s is a directory", argv[1]);
	free(d);

	if((b1 = Bopen(argv[0], OREAD)) == nil)
		sysfatal("open %s: %r", argv[0]);
	if((b2 = Bopen(argv[1], OREAD)) == nil)
		sysfatal("open %s: %r", argv[1]);

	strcpy(diffout, "/tmp/idiff.XXXXXX");
	fd = opentemp(diffout, ORDWR|ORCLOSE, 0);
	strcpy(idiffout, "/tmp/idiff.XXXXXX");
	ofd = opentemp(idiffout, ORDWR|ORCLOSE, 0);
	rundiff(argv[0], argv[1], fd);
	seek(fd, 0, 0);
	Binit(&bdiff, fd, OREAD);
	Binit(&bout, ofd, OWRITE);
	idiff(b1, argv[0], b2, argv[1], &bdiff, diffout, &bout, idiffout);
	Bterm(&bdiff);
	Bflush(&bout);
	seek(ofd, 0, 0);
	Binit(&bout, ofd, OREAD);
	Binit(&bstdout, 1, OWRITE);
	copy(&bout, idiffout, &bstdout, "<stdout>");
	exits(nil);
}

int
opentemp(char *template, int mode, long perm)
{
	int fd;
	Dir d;

	fd = mkstemp(template);
	if(fd < 0)
		sysfatal("could not create temporary file");
	nulldir(&d);
	d.mode = perm;
	dirfwstat(fd, &d);

	return fd;
}

void
rundiff(char *arg1, char *arg2, int outfd)
{
	char *arg[10], *p;
	int narg, pid;
	Waitmsg *w;

	narg = 0;
	arg[narg++] = "diff";
	arg[narg++] = "-n";
	if(diffbflag)
		arg[narg++] = "-b";
	if(diffwflag)
		arg[narg++] = "-w";
	arg[narg++] = arg1;
	arg[narg++] = arg2;
	arg[narg] = nil;

	switch(pid = fork()){
	case -1:
		sysfatal("fork: %r");

	case 0:
		dup(outfd, 1);
		close(0);
		exec("diff", arg);
		sysfatal("exec: %r");

	default:
		w = wait();
		if(w==nil)
			sysfatal("wait: %r");
		if(w->pid != pid)
			sysfatal("wait got unexpected pid %d", w->pid);
		if((p = strchr(w->msg, ':')) && strcmp(p, ": some") != 0)
			sysfatal("%s", w->msg);
		free(w);
	}
}

void
runcmd(char *cmd)
{
	char *arg[10];
	int narg, pid, wpid;

	narg = 0;
	arg[narg++] = "rc";
	arg[narg++] = "-c";
	arg[narg++] = cmd;
	arg[narg] = nil;

	switch(pid = fork()){
	case -1:
		sysfatal("fork: %r");

	case 0:
		exec("rc", arg);
		sysfatal("exec: %r");

	default:
		wpid = waitpid();
		if(wpid < 0)
			sysfatal("wait: %r");
		if(wpid != pid)
			sysfatal("wait got unexpected pid %d", wpid);
	}
}

void
parse(char *s, int *pfrom1, int *pto1, int *pcmd, int *pfrom2, int *pto2)
{
	*pfrom1 = *pto1 = *pfrom2 = *pto2 = 0;

	s = strchr(s, ':');
	if(s == nil)
		sysfatal("bad diff output0");
	s++;
	*pfrom1 = strtol(s, &s, 10);
	if(*s == ','){
		s++;
		*pto1 = strtol(s, &s, 10);
	}else
		*pto1 = *pfrom1;
	if(*s++ != ' ')
		sysfatal("bad diff output1");
	*pcmd = *s++;
	if(*s++ != ' ')
		sysfatal("bad diff output2");
	s = strchr(s, ':');
	if(s == nil)
		sysfatal("bad diff output3");
	s++;
	*pfrom2 = strtol(s, &s, 10);
	if(*s == ','){
		s++;
		*pto2 = strtol(s, &s, 10);
	}else
		*pto2 = *pfrom2;
}

void
skiplines(Biobuf *b, char *name, int n)
{
	int i;

	for(i=0; i<n; i++){
		while(Brdline(b, '\n')==nil){
			if(Blinelen(b) <= 0)
				sysfatal("early end of file on %s", name);
			Bseek(b, Blinelen(b), 1);
		}
	}
}

void
copylines(Biobuf *bin, char *nin, Biobuf *bout, char *nout, int n)
{
	char buf[4096], *p;
	int i, m;

	for(i=0; i<n; i++){
		while((p=Brdline(bin, '\n'))==nil){
			if(Blinelen(bin) <= 0)
				sysfatal("early end of file on %s", nin);
			m = Blinelen(bin);
			if(m > sizeof buf)
				m = sizeof buf;
			m = Bread(bin, buf, m);
			if(Bwrite(bout, buf, m) != m)
				sysfatal("error writing %s: %r", nout);
		}
		if(Bwrite(bout, p, Blinelen(bin)) != Blinelen(bin))
			sysfatal("error writing %s: %r", nout);
	}
}

void
copy(Biobuf *bin, char *nin, Biobuf *bout, char *nout)
{
	char buf[4096];
	int m;

	USED(nin);
	while((m = Bread(bin, buf, sizeof buf)) > 0)
		if(Bwrite(bout, buf, m) != m)
			sysfatal("error writing %s: %r", nout);
}

void
idiff(Biobuf *b1, char *name1, Biobuf *b2, char *name2, Biobuf *bdiff, char *namediff, Biobuf *bout, char *nameout)
{
	char buf[256], *p;
	int interactive, defaultanswer, cmd, diffoffset;
	int n, from1, to1, from2, to2, nf1, nf2;
	Biobuf berr;

	nf1 = 1;
	nf2 = 1;
	interactive = 1;
	defaultanswer = 0;
	Binit(&berr, 2, OWRITE);
	while(diffoffset = Boffset(bdiff), p = Brdline(bdiff, '\n')){
		p[Blinelen(bdiff)-1] = '\0';
		parse(p, &from1, &to1, &cmd, &from2, &to2);
		p[Blinelen(bdiff)-1] = '\n';
		n = to1-from1 + to2-from2 + 1;	/* #lines from diff */
		if(cmd == 'c')
			n += 2;
		else if(cmd == 'a')
			from1++;
		else if(cmd == 'd')
			from2++;
		to1++;	/* make half-open intervals */
		to2++;
		if(interactive){
			p[Blinelen(bdiff)-1] = '\0';
			fprint(2, "%s\n", p);
			p[Blinelen(bdiff)-1] = '\n';
			copylines(bdiff, namediff, &berr, "<stderr>", n);
			Bflush(&berr);
		}else
			skiplines(bdiff, namediff, n);
		do{
			if(interactive){
				fprint(2, "? ");
				memset(buf, 0, sizeof buf);
				if(read(0, buf, sizeof buf - 1) < 0)
					sysfatal("read console: %r");
			}else
				buf[0] = defaultanswer;

			switch(buf[0]){
			case '>':
				copylines(b1, name1, bout, nameout, from1-nf1);
				skiplines(b1, name1, to1-from1);
				skiplines(b2, name2, from2-nf2);
				copylines(b2, name2, bout, nameout, to2-from2);
				break;
			case '<':
				copylines(b1, name1, bout, nameout, to1-nf1);
				skiplines(b2, name2, to2-nf2);
				break;
			case '=':
				copylines(b1, name1, bout, nameout, from1-nf1);
				skiplines(b1, name1, to1-from1);
				skiplines(b2, name2, to2-nf2);
				if(Bseek(bdiff, diffoffset, 0) != diffoffset)
					sysfatal("seek in diff output: %r");
				copylines(bdiff, namediff, bout, nameout, n+1);
				break;
			case '!':
				runcmd(buf+1);
				break;
			case 'q':
				if(buf[1]=='<' || buf[1]=='>' || buf[1]=='='){
					interactive = 0;
					defaultanswer = buf[1];
				}else
					fprint(2, "must be q<, q>, or q=\n");
				break;
			default:
				fprint(2, "expect: <, >, =, q<, q>, q=, !cmd\n");
				break;
			}
		}while(buf[0] != '<' && buf[0] != '>' && buf[0] != '=');
		nf1 = to1;
		nf2 = to2;
	}
	copy(b1, name1, bout, nameout);
}
