#include "sam.h"

Rune	genbuf[BLOCKSIZE];
int	io;
int	panicking;
int	rescuing;
String	genstr;
String	rhs;
String	curwd;
String	cmdstr;
Rune	empty[] = { 0 };
char	*genc;
File	*curfile;
File	*flist;
File	*cmd;
jmp_buf	mainloop;
List	tempfile;
int	quitok = TRUE;
int	downloaded;
int	dflag;
int	Rflag;
char	*machine;
char	*home;
int	bpipeok;
int	termlocked;
char	*samterm = SAMTERM;
char	*rsamname = RSAM;
File	*lastfile;
Disk	*disk;
long	seq;

char *winsize;

Rune	baddir[] = { '<', 'b', 'a', 'd', 'd', 'i', 'r', '>', '\n'};

void	usage(void);

extern int notify(void(*)(void*,char*));

int
main(int volatile argc, char **volatile argv)
{
	int volatile i;
	String *t;
	char *termargs[10], **ap;
	
	ap = termargs;
	*ap++ = "samterm";
	ARGBEGIN{
	case 'd':
		dflag++;
		break;
	case 'r':
		machine = EARGF(usage());
		break;
	case 'R':
		Rflag++;
		break;
	case 't':
		samterm = EARGF(usage());
		break;
	case 's':
		rsamname = EARGF(usage());
		break;
	default:
		dprint("sam: unknown flag %c\n", ARGC());
		usage();
	/* options for samterm */
	case 'a':
		*ap++ = "-a";
		break;
	case 'W':
		*ap++ = "-W";
		*ap++ = EARGF(usage());
		break;
	}ARGEND
	*ap = nil;

	Strinit(&cmdstr);
	Strinit0(&lastpat);
	Strinit0(&lastregexp);
	Strinit0(&genstr);
	Strinit0(&rhs);
	Strinit0(&curwd);
	tempfile.listptr = emalloc(1);	/* so it can be freed later */
	Strinit0(&plan9cmd);
	home = getenv(HOME);
	disk = diskinit();
	if(home == 0)
		home = "/";
	if(!dflag)
		startup(machine, Rflag, termargs, argv);
	notify(notifyf);
	getcurwd();
	if(argc>0){
		for(i=0; i<argc; i++){
			if(!setjmp(mainloop)){
				t = tmpcstr(argv[i]);
				Straddc(t, '\0');
				Strduplstr(&genstr, t);
				freetmpstr(t);
				fixname(&genstr);
				logsetname(newfile(), &genstr);
			}
		}
	}else if(!downloaded)
		newfile();
	seq++;
	if(file.nused)
		current(file.filepptr[0]);
	setjmp(mainloop);
	cmdloop();
	trytoquit();	/* if we already q'ed, quitok will be TRUE */
	exits(0);
	return 0;
}

void
usage(void)
{
	dprint("usage: sam [-d] [-t samterm] [-s sam name] -r machine\n");
	exits("usage");
}

void
rescue(void)
{
	int i, nblank = 0;
	File *f;
	char *c;
	char buf[256];
	char *root;

	if(rescuing++)
		return;
	io = -1;
	for(i=0; i<file.nused; i++){
		f = file.filepptr[i];
		if(f==cmd || f->b.nc==0 || !fileisdirty(f))
			continue;
		if(io == -1){
			sprint(buf, "%s/sam.save", home);
			io = create(buf, 1, 0777);
			if(io<0)
				return;
		}
		if(f->name.s[0]){
			c = Strtoc(&f->name);
			strncpy(buf, c, sizeof buf-1);
			buf[sizeof buf-1] = 0;
			free(c);
		}else
			sprint(buf, "nameless.%d", nblank++);
		root = getenv("PLAN9");
		if(root == nil)
			root = "/usr/local/plan9";
		fprint(io, "#!/bin/sh\n%s/bin/samsave '%s' $* <<'---%s'\n", root, buf, buf);
		addr.r.p1 = 0, addr.r.p2 = f->b.nc;
		writeio(f);
		fprint(io, "\n---%s\n", (char *)buf);
	}
}

void
panic(char *s)
{
	int wasd;

	if(!panicking++ && !setjmp(mainloop)){
		wasd = downloaded;
		downloaded = 0;
		dprint("sam: panic: %s: %r\n", s);
		if(wasd)
			fprint(2, "sam: panic: %s: %r\n", s);
		rescue();
		abort();
	}
}

void
hiccough(char *s)
{
	File *f;
	int i;

	if(rescuing)
		exits("rescue");
	if(s)
		dprint("%s\n", s);
	resetcmd();
	resetxec();
	resetsys();
	if(io > 0)
		close(io);

	/*
	 * back out any logged changes & restore old sequences
	 */
	for(i=0; i<file.nused; i++){
		f = file.filepptr[i];
		if(f==cmd)
			continue;
		if(f->seq==seq){
			bufdelete(&f->epsilon, 0, f->epsilon.nc);
			f->seq = f->prevseq;
			f->dot.r = f->prevdot;
			f->mark = f->prevmark;
			state(f, f->prevmod ? Dirty: Clean);
		}
	}

	update();
	if (curfile) {
		if (curfile->unread)
			curfile->unread = FALSE;
		else if (downloaded)
			outTs(Hcurrent, curfile->tag);
	}
	longjmp(mainloop, 1);
}

void
intr(void)
{
	error(Eintr);
}

void
trytoclose(File *f)
{
	char *t;
	char buf[256];

	if(f == cmd)	/* possible? */
		return;
	if(f->deleted)
		return;
	if(fileisdirty(f) && !f->closeok){
		f->closeok = TRUE;
		if(f->name.s[0]){
			t = Strtoc(&f->name);
			strncpy(buf, t, sizeof buf-1);
			free(t);
		}else
			strcpy(buf, "nameless file");
		error_s(Emodified, buf);
	}
	f->deleted = TRUE;
}

void
trytoquit(void)
{
	int c;
	File *f;

	if(!quitok){
		for(c = 0; c<file.nused; c++){
			f = file.filepptr[c];
			if(f!=cmd && fileisdirty(f)){
				quitok = TRUE;
				eof = FALSE;
				error(Echanges);
			}
		}
	}
}

void
load(File *f)
{
	Address saveaddr;

	Strduplstr(&genstr, &f->name);
	filename(f);
	if(f->name.s[0]){
		saveaddr = addr;
		edit(f, 'I');
		addr = saveaddr;
	}else{
		f->unread = 0;
		f->cleanseq = f->seq;
	}

	fileupdate(f, TRUE, TRUE);
}

void
cmdupdate(void)
{
	if(cmd && cmd->seq!=0){
		fileupdate(cmd, FALSE, downloaded);
		cmd->dot.r.p1 = cmd->dot.r.p2 = cmd->b.nc;
		telldot(cmd);
	}
}

void
delete(File *f)
{
	if(downloaded && f->rasp)
		outTs(Hclose, f->tag);
	delfile(f);
	if(f == curfile)
		current(0);
}

void
update(void)
{
	int i, anymod;
	File *f;

	settempfile();
	for(anymod = i=0; i<tempfile.nused; i++){
		f = tempfile.filepptr[i];
		if(f==cmd)	/* cmd gets done in main() */
			continue;
		if(f->deleted) {
			delete(f);
			continue;
		}
		if(f->seq==seq && fileupdate(f, FALSE, downloaded))
			anymod++;
		if(f->rasp)
			telldot(f);
	}
	if(anymod)
		seq++;
}

File *
current(File *f)
{
	return curfile = f;
}

void
edit(File *f, int cmd)
{
	int empty = TRUE;
	Posn p;
	int nulls;

	if(cmd == 'r')
		logdelete(f, addr.r.p1, addr.r.p2);
	if(cmd=='e' || cmd=='I'){
		logdelete(f, (Posn)0, f->b.nc);
		addr.r.p2 = f->b.nc;
	}else if(f->b.nc!=0 || (f->name.s[0] && Strcmp(&genstr, &f->name)!=0))
		empty = FALSE;
	if((io = open(genc, OREAD))<0) {
		if (curfile && curfile->unread)
			curfile->unread = FALSE;
		error_r(Eopen, genc);
	}
	p = readio(f, &nulls, empty, TRUE);
	closeio((cmd=='e' || cmd=='I')? -1 : p);
	if(cmd == 'r')
		f->ndot.r.p1 = addr.r.p2, f->ndot.r.p2 = addr.r.p2+p;
	else
		f->ndot.r.p1 = f->ndot.r.p2 = 0;
	f->closeok = empty;
	if (quitok)
		quitok = empty;
	else
		quitok = FALSE;
	state(f, empty && !nulls? Clean : Dirty);
	if(empty && !nulls)
		f->cleanseq = f->seq;
	if(cmd == 'e')
		filename(f);
}

int
getname(File *f, String *s, int save)
{
	int c, i;

	Strzero(&genstr);
	if(genc){
		free(genc);
		genc = 0;
	}
	if(s==0 || (c = s->s[0])==0){		/* no name provided */
		if(f)
			Strduplstr(&genstr, &f->name);
		goto Return;
	}
	if(c!=' ' && c!='\t')
		error(Eblank);
	for(i=0; (c=s->s[i])==' ' || c=='\t'; i++)
		;
	while(s->s[i] > ' ')
		Straddc(&genstr, s->s[i++]);
	if(s->s[i])
		error(Enewline);
	fixname(&genstr);
	if(f && (save || f->name.s[0]==0)){
		logsetname(f, &genstr);
		if(Strcmp(&f->name, &genstr)){
			quitok = f->closeok = FALSE;
			f->qidpath = 0;
			f->mtime = 0;
			state(f, Dirty); /* if it's 'e', fix later */
		}
	}
    Return:
	genc = Strtoc(&genstr);
	i = genstr.n;
	if(i && genstr.s[i-1]==0)
		i--;
	return i;	/* strlen(name) */
}

void
filename(File *f)
{
	if(genc)
		free(genc);
	genc = Strtoc(&genstr);
	dprint("%c%c%c %s\n", " '"[f->mod],
		"-+"[f->rasp!=0], " ."[f==curfile], genc);
}

void
undostep(File *f, int isundo)
{
	uint p1, p2;
	int mod;

	mod = f->mod;
	fileundo(f, isundo, 1, &p1, &p2, TRUE);
	f->ndot = f->dot;
	if(f->mod){
		f->closeok = 0;
		quitok = 0;
	}else
		f->closeok = 1;

	if(f->mod != mod){
		f->mod = mod;
		if(mod)
			mod = Clean;
		else
			mod = Dirty;
		state(f, mod);
	}
}

int
undo(int isundo)
{
	File *f;
	int i;
	Mod max;

	max = undoseq(curfile, isundo);
	if(max == 0)
		return 0;
	settempfile();
	for(i = 0; i<tempfile.nused; i++){
		f = tempfile.filepptr[i];
		if(f!=cmd && undoseq(f, isundo)==max)
			undostep(f, isundo);
	}
	return 1;
}

int
readcmd(String *s)
{
	int retcode;

	if(flist != 0)
		fileclose(flist);
	flist = fileopen();

	addr.r.p1 = 0, addr.r.p2 = flist->b.nc;
	retcode = plan9(flist, '<', s, FALSE);
	fileupdate(flist, FALSE, FALSE);
	flist->seq = 0;
	if (flist->b.nc > BLOCKSIZE)
		error(Etoolong);
	Strzero(&genstr);
	Strinsure(&genstr, flist->b.nc);
	bufread(&flist->b, (Posn)0, genbuf, flist->b.nc);
	memmove(genstr.s, genbuf, flist->b.nc*RUNESIZE);
	genstr.n = flist->b.nc;
	Straddc(&genstr, '\0');
	return retcode;
}

void
getcurwd(void)
{
	String *t;
	char buf[256];

	buf[0] = 0;
	getwd(buf, sizeof(buf));
	t = tmpcstr(buf);
	Strduplstr(&curwd, t);
	freetmpstr(t);
	if(curwd.n == 0)
		warn(Wpwd);
	else if(curwd.s[curwd.n-1] != '/')
		Straddc(&curwd, '/');
}

void
cd(String *str)
{
	int i, fd;
	char *s;
	File *f;
	String owd;

	getcurwd();
	if(getname((File *)0, str, FALSE))
		s = genc;
	else
		s = home;
	if(chdir(s))
		syserror("chdir");
	fd = open("/dev/wdir", OWRITE);
	if(fd > 0)
		write(fd, s, strlen(s));
	dprint("!\n");
	Strinit(&owd);
	Strduplstr(&owd, &curwd);
	getcurwd();
	settempfile();
	for(i=0; i<tempfile.nused; i++){
		f = tempfile.filepptr[i];
		if(f!=cmd && f->name.s[0]!='/' && f->name.s[0]!=0){
			Strinsert(&f->name, &owd, (Posn)0);
			fixname(&f->name);
			sortname(f);
		}else if(f != cmd && Strispre(&curwd, &f->name)){
			fixname(&f->name);
			sortname(f);
		}
	}
	Strclose(&owd);
}

int
loadflist(String *s)
{
	int c, i;

	c = s->s[0];
	for(i = 0; s->s[i]==' ' || s->s[i]=='\t'; i++)
		;
	if((c==' ' || c=='\t') && s->s[i]!='\n'){
		if(s->s[i]=='<'){
			Strdelete(s, 0L, (long)i+1);
			readcmd(s);
		}else{
			Strzero(&genstr);
			while((c = s->s[i++]) && c!='\n')
				Straddc(&genstr, c);
			Straddc(&genstr, '\0');
		}
	}else{
		if(c != '\n')
			error(Eblank);
		Strdupl(&genstr, empty);
	}
	if(genc)
		free(genc);
	genc = Strtoc(&genstr);
	return genstr.s[0];
}

File *
readflist(int readall, int delete)
{
	Posn i;
	int c;
	File *f;
	String t;

	Strinit(&t);
	for(i=0,f=0; f==0 || readall || delete; i++){	/* ++ skips blank */
		Strdelete(&genstr, (Posn)0, i);
		for(i=0; (c = genstr.s[i])==' ' || c=='\t' || c=='\n'; i++)
			;
		if(i >= genstr.n)
			break;
		Strdelete(&genstr, (Posn)0, i);
		for(i=0; (c=genstr.s[i]) && c!=' ' && c!='\t' && c!='\n'; i++)
			;

		if(i == 0)
			break;
		genstr.s[i] = 0;
		Strduplstr(&t, tmprstr(genstr.s, i+1));
		fixname(&t);
		f = lookfile(&t);
		if(delete){
			if(f == 0)
				warn_S(Wfile, &t);
			else
				trytoclose(f);
		}else if(f==0 && readall)
			logsetname(f = newfile(), &t);
	}
	Strclose(&t);
	return f;
}

File *
tofile(String *s)
{
	File *f;

	if(s->s[0] != ' ')
		error(Eblank);
	if(loadflist(s) == 0){
		f = lookfile(&genstr);	/* empty string ==> nameless file */
		if(f == 0)
			error_s(Emenu, genc);
	}else if((f=readflist(FALSE, FALSE)) == 0)
		error_s(Emenu, genc);
	return current(f);
}

File *
getfile(String *s)
{
	File *f;

	if(loadflist(s) == 0)
		logsetname(f = newfile(), &genstr);
	else if((f=readflist(TRUE, FALSE)) == 0)
		error(Eblank);
	return current(f);
}

void
closefiles(File *f, String *s)
{
	if(s->s[0] == 0){
		if(f == 0)
			error(Enofile);
		trytoclose(f);
		return;
	}
	if(s->s[0] != ' ')
		error(Eblank);
	if(loadflist(s) == 0)
		error(Enewline);
	readflist(FALSE, TRUE);
}

void
copy(File *f, Address addr2)
{
	Posn p;
	int ni;
	for(p=addr.r.p1; p<addr.r.p2; p+=ni){
		ni = addr.r.p2-p;
		if(ni > BLOCKSIZE)
			ni = BLOCKSIZE;
		bufread(&f->b, p, genbuf, ni);
		loginsert(addr2.f, addr2.r.p2, tmprstr(genbuf, ni)->s, ni);
	}
	addr2.f->ndot.r.p2 = addr2.r.p2+(f->dot.r.p2-f->dot.r.p1);
	addr2.f->ndot.r.p1 = addr2.r.p2;
}

void
move(File *f, Address addr2)
{
	if(addr.r.p2 <= addr2.r.p2){
		logdelete(f, addr.r.p1, addr.r.p2);
		copy(f, addr2);
	}else if(addr.r.p1 >= addr2.r.p2){
		copy(f, addr2);
		logdelete(f, addr.r.p1, addr.r.p2);
	}else
		error(Eoverlap);
}

Posn
nlcount(File *f, Posn p0, Posn p1)
{
	Posn nl = 0;

	while(p0 < p1)
		if(filereadc(f, p0++)=='\n')
			nl++;
	return nl;
}

void
printposn(File *f, int charsonly)
{
	Posn l1, l2;

	if(!charsonly){
		l1 = 1+nlcount(f, (Posn)0, addr.r.p1);
		l2 = l1+nlcount(f, addr.r.p1, addr.r.p2);
		/* check if addr ends with '\n' */
		if(addr.r.p2>0 && addr.r.p2>addr.r.p1 && filereadc(f, addr.r.p2-1)=='\n')
			--l2;
		dprint("%lud", l1);
		if(l2 != l1)
			dprint(",%lud", l2);
		dprint("; ");
	}
	dprint("#%lud", addr.r.p1);
	if(addr.r.p2 != addr.r.p1)
		dprint(",#%lud", addr.r.p2);
	dprint("\n");
}

void
settempfile(void)
{
	if(tempfile.nalloc < file.nused){
		free(tempfile.listptr);
		tempfile.listptr = emalloc(sizeof(*tempfile.filepptr)*file.nused);
		tempfile.nalloc = file.nused;
	}
	tempfile.nused = file.nused;
	memmove(&tempfile.filepptr[0], &file.filepptr[0], file.nused*sizeof(File*));
}
