#include "sam.h"
Header	h;
uchar	indata[DATASIZE];
uchar	outdata[2*DATASIZE+3];	/* room for overflow message */
uchar	*inp;
uchar	*outp;
uchar	*outmsg = outdata;
Posn	cmdpt;
Posn	cmdptadv;
Buffer	snarfbuf;
int	waitack;
int	outbuffered;
int	tversion;

int	inshort(void);
long	inlong(void);
vlong	invlong(void);
int	inmesg(Tmesg);

void	outshort(int);
void	outlong(long);
void	outvlong(vlong);
void	outcopy(int, void*);
void	outsend(void);
void	outstart(Hmesg);

void	setgenstr(File*, Posn, Posn);

#ifdef DEBUG
char *hname[] = {
	[Hversion]	"Hversion",
	[Hbindname]	"Hbindname",
	[Hcurrent]	"Hcurrent",
	[Hnewname]	"Hnewname",
	[Hmovname]	"Hmovname",
	[Hgrow]		"Hgrow",
	[Hcheck0]	"Hcheck0",
	[Hcheck]	"Hcheck",
	[Hunlock]	"Hunlock",
	[Hdata]		"Hdata",
	[Horigin]	"Horigin",
	[Hunlockfile]	"Hunlockfile",
	[Hsetdot]	"Hsetdot",
	[Hgrowdata]	"Hgrowdata",
	[Hmoveto]	"Hmoveto",
	[Hclean]	"Hclean",
	[Hdirty]	"Hdirty",
	[Hcut]		"Hcut",
	[Hsetpat]	"Hsetpat",
	[Hdelname]	"Hdelname",
	[Hclose]	"Hclose",
	[Hsetsnarf]	"Hsetsnarf",
	[Hsnarflen]	"Hsnarflen",
	[Hack]		"Hack",
	[Hexit]		"Hexit",
	[Hplumb]		"Hplumb"
};

char *tname[] = {
	[Tversion]	"Tversion",
	[Tstartcmdfile]	"Tstartcmdfile",
	[Tcheck]	"Tcheck",
	[Trequest]	"Trequest",
	[Torigin]	"Torigin",
	[Tstartfile]	"Tstartfile",
	[Tworkfile]	"Tworkfile",
	[Ttype]		"Ttype",
	[Tcut]		"Tcut",
	[Tpaste]	"Tpaste",
	[Tsnarf]	"Tsnarf",
	[Tstartnewfile]	"Tstartnewfile",
	[Twrite]	"Twrite",
	[Tclose]	"Tclose",
	[Tlook]		"Tlook",
	[Tsearch]	"Tsearch",
	[Tsend]		"Tsend",
	[Tdclick]	"Tdclick",
	[Tstartsnarf]	"Tstartsnarf",
	[Tsetsnarf]	"Tsetsnarf",
	[Tack]		"Tack",
	[Texit]		"Texit",
	[Tplumb]		"Tplumb"
};

void
journal(int out, char *s)
{
	static int fd = 0;

	if(fd <= 0)
		fd = create("/tmp/sam.out", 1, 0666L);
	fprint(fd, "%s%s\n", out? "out: " : "in:  ", s);
}

void
journaln(int out, long n)
{
	char buf[32];

	snprint(buf, sizeof buf, "%ld", n);
	journal(out, buf);
}

void
journalv(int out, vlong v)
{
	char buf[32];

	snprint(buf, sizeof buf, "%lld", v);
	journal(out, buf);
}

#else
#define	journal(a, b)
#define journaln(a, b)
#endif

int
rcvchar(void){
	static uchar buf[64];
	static int i, nleft = 0;

	if(nleft <= 0){
		nleft = read(0, (char *)buf, sizeof buf);
		if(nleft <= 0)
			return -1;
		i = 0;
	}
	--nleft;
	return buf[i++];
}

int
rcv(void){
	int c;
	static int state = 0;
	static int count = 0;
	static int i = 0;

	while((c=rcvchar()) != -1)
		switch(state){
		case 0:
			h.type = c;
			state++;
			break;

		case 1:
			h.count0 = c;
			state++;
			break;

		case 2:
			h.count1 = c;
			count = h.count0|(h.count1<<8);
			i = 0;
			if(count > DATASIZE)
				panic("count>DATASIZE");
			if(count == 0)
				goto zerocount;
			state++;
			break;

		case 3:
			indata[i++] = c;
			if(i == count){
		zerocount:
				indata[i] = 0;
				state = count = 0;
				return inmesg(h.type);
			}
			break;
		}
	return 0;
}

File *
whichfile(int tag)
{
	int i;

	for(i = 0; i<file.nused; i++)
		if(file.filepptr[i]->tag==tag)
			return file.filepptr[i];
	hiccough((char *)0);
	return 0;
}

int
inmesg(Tmesg type)
{
	Rune buf[1025];
	char cbuf[64];
	int i, m;
	short s;
	long l, l1;
	vlong v;
	File *f;
	Posn p0, p1, p;
	Range r;
	String *str;
	char *c, *wdir;
	Rune *rp;
	Plumbmsg *pm;

	if(type > TMAX)
		panic("inmesg");

	journal(0, tname[type]);

	inp = indata;
	switch(type){
	case -1:
		panic("rcv error");

	default:
		fprint(2, "unknown type %d\n", type);
		panic("rcv unknown");

	case Tversion:
		tversion = inshort();
		journaln(0, tversion);
		break;

	case Tstartcmdfile:
		v = invlong();		/* for 64-bit pointers */
		journaln(0, v);
		Strdupl(&genstr, samname);
		cmd = newfile();
		cmd->unread = 0;
		outTsv(Hbindname, cmd->tag, v);
		outTs(Hcurrent, cmd->tag);
		logsetname(cmd, &genstr);
		cmd->rasp = listalloc('P');
		cmd->mod = 0;
		if(cmdstr.n){
			loginsert(cmd, 0L, cmdstr.s, cmdstr.n);
			Strdelete(&cmdstr, 0L, (Posn)cmdstr.n);
		}
		fileupdate(cmd, FALSE, TRUE);
		outT0(Hunlock);
		break;

	case Tcheck:
		/* go through whichfile to check the tag */
		outTs(Hcheck, whichfile(inshort())->tag);
		break;

	case Trequest:
		f = whichfile(inshort());
		p0 = inlong();
		p1 = p0+inshort();
		journaln(0, p0);
		journaln(0, p1-p0);
		if(f->unread)
			panic("Trequest: unread");
		if(p1>f->b.nc)
			p1 = f->b.nc;
		if(p0>f->b.nc) /* can happen e.g. scrolling during command */
			p0 = f->b.nc;
		if(p0 == p1){
			i = 0;
			r.p1 = r.p2 = p0;
		}else{
			r = rdata(f->rasp, p0, p1-p0);
			i = r.p2-r.p1;
			bufread(&f->b, r.p1, buf, i);
		}
		buf[i]=0;
		outTslS(Hdata, f->tag, r.p1, tmprstr(buf, i+1));
		break;

	case Torigin:
		s = inshort();
		l = inlong();
		l1 = inlong();
		journaln(0, l1);
		lookorigin(whichfile(s), l, l1);
		break;

	case Tstartfile:
		termlocked++;
		f = whichfile(inshort());
		if(!f->rasp)	/* this might be a duplicate message */
			f->rasp = listalloc('P');
		current(f);
		outTsv(Hbindname, f->tag, invlong());	/* for 64-bit pointers */
		outTs(Hcurrent, f->tag);
		journaln(0, f->tag);
		if(f->unread)
			load(f);
		else{
			if(f->b.nc>0){
				rgrow(f->rasp, 0L, f->b.nc);
				outTsll(Hgrow, f->tag, 0L, f->b.nc);
			}
			outTs(Hcheck0, f->tag);
			moveto(f, f->dot.r);
		}
		break;

	case Tworkfile:
		i = inshort();
		f = whichfile(i);
		current(f);
		f->dot.r.p1 = inlong();
		f->dot.r.p2 = inlong();
		f->tdot = f->dot.r;
		journaln(0, i);
		journaln(0, f->dot.r.p1);
		journaln(0, f->dot.r.p2);
		break;

	case Ttype:
		f = whichfile(inshort());
		p0 = inlong();
		journaln(0, p0);
		journal(0, (char*)inp);
		str = tmpcstr((char*)inp);
		i = str->n;
		loginsert(f, p0, str->s, str->n);
		if(fileupdate(f, FALSE, FALSE))
			seq++;
		if(f==cmd && p0==f->b.nc-i && i>0 && str->s[i-1]=='\n'){
			freetmpstr(str);
			termlocked++;
			termcommand();
		}else
			freetmpstr(str);
		f->dot.r.p1 = f->dot.r.p2 = p0+i; /* terminal knows this already */
		f->tdot = f->dot.r;
		break;

	case Tcut:
		f = whichfile(inshort());
		p0 = inlong();
		p1 = inlong();
		journaln(0, p0);
		journaln(0, p1);
		logdelete(f, p0, p1);
		if(fileupdate(f, FALSE, FALSE))
			seq++;
		f->dot.r.p1 = f->dot.r.p2 = p0;
		f->tdot = f->dot.r;   /* terminal knows the value of dot already */
		break;

	case Tpaste:
		f = whichfile(inshort());
		p0 = inlong();
		journaln(0, p0);
		for(l=0; l<snarfbuf.nc; l+=m){
			m = snarfbuf.nc-l;
			if(m>BLOCKSIZE)
				m = BLOCKSIZE;
			bufread(&snarfbuf, l, genbuf, m);
			loginsert(f, p0, tmprstr(genbuf, m)->s, m);
		}
		if(fileupdate(f, FALSE, TRUE))
			seq++;
		f->dot.r.p1 = p0;
		f->dot.r.p2 = p0+snarfbuf.nc;
		f->tdot.p1 = -1; /* force telldot to tell (arguably a BUG) */
		telldot(f);
		outTs(Hunlockfile, f->tag);
		break;

	case Tsnarf:
		i = inshort();
		p0 = inlong();
		p1 = inlong();
		snarf(whichfile(i), p0, p1, &snarfbuf, 0);
		break;

	case Tstartnewfile:
		v = invlong();
		Strdupl(&genstr, empty);
		f = newfile();
		f->rasp = listalloc('P');
		outTsv(Hbindname, f->tag, v);
		logsetname(f, &genstr);
		outTs(Hcurrent, f->tag);
		current(f);
		load(f);
		break;

	case Twrite:
		termlocked++;
		i = inshort();
		journaln(0, i);
		f = whichfile(i);
		addr.r.p1 = 0;
		addr.r.p2 = f->b.nc;
		if(f->name.s[0] == 0)
			error(Enoname);
		Strduplstr(&genstr, &f->name);
		writef(f);
		break;

	case Tclose:
		termlocked++;
		i = inshort();
		journaln(0, i);
		f = whichfile(i);
		current(f);
		trytoclose(f);
		/* if trytoclose fails, will error out */
		delete(f);
		break;

	case Tlook:
		f = whichfile(inshort());
		termlocked++;
		p0 = inlong();
		p1 = inlong();
		journaln(0, p0);
		journaln(0, p1);
		setgenstr(f, p0, p1);
		for(l = 0; l<genstr.n; l++){
			i = genstr.s[l];
			if(utfrune(".*+?(|)\\[]^$", i)){
				str = tmpcstr("\\");
				Strinsert(&genstr, str, l++);
				freetmpstr(str);
			}
		}
		Straddc(&genstr, '\0');
		nextmatch(f, &genstr, p1, 1);
		moveto(f, sel.p[0]);
		break;

	case Tsearch:
		termlocked++;
		if(curfile == 0)
			error(Enofile);
		if(lastpat.s[0] == 0)
			panic("Tsearch");
		nextmatch(curfile, &lastpat, curfile->dot.r.p2, 1);
		moveto(curfile, sel.p[0]);
		break;

	case Tsend:
		termlocked++;
		inshort();	/* ignored */
		p0 = inlong();
		p1 = inlong();
		setgenstr(cmd, p0, p1);
		bufreset(&snarfbuf);
		bufinsert(&snarfbuf, (Posn)0, genstr.s, genstr.n);
		outTl(Hsnarflen, genstr.n);
		if(genstr.s[genstr.n-1] != '\n')
			Straddc(&genstr, '\n');
		loginsert(cmd, cmd->b.nc, genstr.s, genstr.n);
		fileupdate(cmd, FALSE, TRUE);
		cmd->dot.r.p1 = cmd->dot.r.p2 = cmd->b.nc;
		telldot(cmd);
		termcommand();
		break;

	case Tdclick:
		f = whichfile(inshort());
		p1 = inlong();
		doubleclick(f, p1);
		f->tdot.p1 = f->tdot.p2 = p1;
		telldot(f);
		outTs(Hunlockfile, f->tag);
		break;

	case Tstartsnarf:
		if (snarfbuf.nc <= 0) {	/* nothing to export */
			outTs(Hsetsnarf, 0);
			break;
		}
		c = 0;
		i = 0;
		m = snarfbuf.nc;
		if(m > SNARFSIZE) {
			m = SNARFSIZE;
			dprint("?warning: snarf buffer truncated\n");
		}
		rp = malloc(m*sizeof(Rune));
		if(rp){
			bufread(&snarfbuf, 0, rp, m);
			c = Strtoc(tmprstr(rp, m));
			free(rp);
			i = strlen(c);
		}
		outTs(Hsetsnarf, i);
		if(c){
			Write(1, c, i);
			free(c);
		} else
			dprint("snarf buffer too long\n");
		break;

	case Tsetsnarf:
		m = inshort();
		if(m > SNARFSIZE)
			error(Etoolong);
		c = malloc(m+1);
		if(c){
			for(i=0; i<m; i++)
				c[i] = rcvchar();
			c[m] = 0;
			str = tmpcstr(c);
			free(c);
			bufreset(&snarfbuf);
			bufinsert(&snarfbuf, (Posn)0, str->s, str->n);
			freetmpstr(str);
			outT0(Hunlock);
		}
		break;

	case Tack:
		waitack = 0;
		break;

	case Tplumb:
		f = whichfile(inshort());
		p0 = inlong();
		p1 = inlong();
		pm = emalloc(sizeof(Plumbmsg));
		pm->src = strdup("sam");
		pm->dst = 0;
		/* construct current directory */
		c = Strtoc(&f->name);
		if(c[0] == '/')
			pm->wdir = c;
		else{
			wdir = emalloc(1024);
			getwd(wdir, 1024);
			pm->wdir = emalloc(1024);
			snprint(pm->wdir, 1024, "%s/%s", wdir, c);
			cleanname(pm->wdir);
			free(wdir);
			free(c);
		}
		c = strrchr(pm->wdir, '/');
		if(c)
			*c = '\0';
		pm->type = strdup("text");
		if(p1 > p0)
			pm->attr = nil;
		else{
			p = p0;
			while(p0>0 && (i=filereadc(f, p0 - 1))!=' ' && i!='\t' && i!='\n')
				p0--;
			while(p1<f->b.nc && (i=filereadc(f, p1))!=' ' && i!='\t' && i!='\n')
				p1++;
			sprint(cbuf, "click=%ld", p-p0);
			pm->attr = plumbunpackattr(cbuf);
		}
		if(p0==p1 || p1-p0>=BLOCKSIZE){
			plumbfree(pm);
			break;
		}
		setgenstr(f, p0, p1);
		pm->data = Strtoc(&genstr);
		pm->ndata = strlen(pm->data);
		c = plumbpack(pm, &i);
		if(c != 0){
			outTs(Hplumb, i);
			Write(1, c, i);
			free(c);
		}
		plumbfree(pm);
		break;

	case Texit:
		exits(0);
	}
	return TRUE;
}

void
snarf(File *f, Posn p1, Posn p2, Buffer *buf, int emptyok)
{
	Posn l;
	int i;

	if(!emptyok && p1==p2)
		return;
	bufreset(buf);
	/* Stage through genbuf to avoid compaction problems (vestigial) */
	if(p2 > f->b.nc){
		fprint(2, "bad snarf addr p1=%ld p2=%ld f->b.nc=%d\n", p1, p2, f->b.nc); /*ZZZ should never happen, can remove */
		p2 = f->b.nc;
	}
	for(l=p1; l<p2; l+=i){
		i = p2-l>BLOCKSIZE? BLOCKSIZE : p2-l;
		bufread(&f->b, l, genbuf, i);
		bufinsert(buf, buf->nc, tmprstr(genbuf, i)->s, i);
	}
}

int
inshort(void)
{
	ushort n;

	n = inp[0] | (inp[1]<<8);
	inp += 2;
	return n;
}

long
inlong(void)
{
	ulong n;

	n = inp[0] | (inp[1]<<8) | (inp[2]<<16) | (inp[3]<<24);
	inp += 4;
	return n;
}

vlong
invlong(void)
{
	vlong v;
	
	v = (inp[7]<<24) | (inp[6]<<16) | (inp[5]<<8) | inp[4];
	v = (v<<16) | (inp[3]<<8) | inp[2];
	v = (v<<16) | (inp[1]<<8) | inp[0];
	inp += 8;
	return v;
}

void
setgenstr(File *f, Posn p0, Posn p1)
{
	if(p0 != p1){
		if(p1-p0 >= TBLOCKSIZE)
			error(Etoolong);
		Strinsure(&genstr, p1-p0);
		bufread(&f->b, p0, genbuf, p1-p0);
		memmove(genstr.s, genbuf, RUNESIZE*(p1-p0));
		genstr.n = p1-p0;
	}else{
		if(snarfbuf.nc == 0)
			error(Eempty);
		if(snarfbuf.nc > TBLOCKSIZE)
			error(Etoolong);
		bufread(&snarfbuf, (Posn)0, genbuf, snarfbuf.nc);
		Strinsure(&genstr, snarfbuf.nc);
		memmove(genstr.s, genbuf, RUNESIZE*snarfbuf.nc);
		genstr.n = snarfbuf.nc;
	}
}

void
outT0(Hmesg type)
{
	outstart(type);
	outsend();
}

void
outTl(Hmesg type, long l)
{
	outstart(type);
	outlong(l);
	outsend();
}

void
outTs(Hmesg type, int s)
{
	outstart(type);
	journaln(1, s);
	outshort(s);
	outsend();
}

void
outS(String *s)
{
	char *c;
	int i;

	c = Strtoc(s);
	i = strlen(c);
	outcopy(i, c);
	if(i > 99)
		c[99] = 0;
	journaln(1, i);
	journal(1, c);
	free(c);
}

void
outTsS(Hmesg type, int s1, String *s)
{
	outstart(type);
	outshort(s1);
	outS(s);
	outsend();
}

void
outTslS(Hmesg type, int s1, Posn l1, String *s)
{
	outstart(type);
	outshort(s1);
	journaln(1, s1);
	outlong(l1);
	journaln(1, l1);
	outS(s);
	outsend();
}

void
outTS(Hmesg type, String *s)
{
	outstart(type);
	outS(s);
	outsend();
}

void
outTsllS(Hmesg type, int s1, Posn l1, Posn l2, String *s)
{
	outstart(type);
	outshort(s1);
	outlong(l1);
	outlong(l2);
	journaln(1, l1);
	journaln(1, l2);
	outS(s);
	outsend();
}

void
outTsll(Hmesg type, int s, Posn l1, Posn l2)
{
	outstart(type);
	outshort(s);
	outlong(l1);
	outlong(l2);
	journaln(1, l1);
	journaln(1, l2);
	outsend();
}

void
outTsl(Hmesg type, int s, Posn l)
{
	outstart(type);
	outshort(s);
	outlong(l);
	journaln(1, l);
	outsend();
}

void
outTsv(Hmesg type, int s, vlong v)
{
	outstart(type);
	outshort(s);
	outvlong(v);
	journaln(1, v);
	outsend();
}

void
outstart(Hmesg type)
{
	journal(1, hname[type]);
	outmsg[0] = type;
	outp = outmsg+3;
}

void
outcopy(int count, void *data)
{
	memmove(outp, data, count);
	outp += count;
}

void
outshort(int s)
{
	*outp++ = s;
	*outp++ = s>>8; 
}

void
outlong(long l)
{
	*outp++ = l;
	*outp++ = l>>8;
	*outp++ = l>>16;
	*outp++ = l>>24;
}

void
outvlong(vlong v)
{
	int i;

	for(i = 0; i < 8; i++){
		*outp++ = v;
		v >>= 8;
	}
}

void
outsend(void)
{
	int outcount;

	if(outp >= outdata+nelem(outdata))
		panic("outsend");
	outcount = outp-outmsg;
	outcount -= 3;
	outmsg[1] = outcount;
	outmsg[2] = outcount>>8;
	outmsg = outp;
	if(!outbuffered){
		outcount = outmsg-outdata;
		if (write(1, (char*) outdata, outcount) != outcount)
			rescue();
		outmsg = outdata;
		return;
	}
}

int
needoutflush(void)
{
	return outmsg >= outdata+DATASIZE;
}

void
outflush(void)
{
	if(outmsg == outdata)
		return;
	outbuffered = 0;
	/* flow control */
	outT0(Hack);
	waitack = 1;
	do
		if(rcv() == 0){
			rescue();
			exits("eof");
		}
	while(waitack);
	outmsg = outdata;
	outbuffered = 1;
}
