#include <u.h>
#include <libc.h>
#include <draw.h>
#include <plumb.h>
#include <regexp.h>
#include <bio.h>
#include <9pclient.h>
#include "faces.h"

enum	/* number of deleted faces to cache */
{
	Nsave	= 20
};

static Facefile	*facefiles;
static int		nsaved;
static char	*facedom;
static char	*libface;
static char	*homeface;

/*
 * Loading the files is slow enough on a dial-up line to be worth this trouble
 */
typedef struct Readcache	Readcache;
struct Readcache {
	char *file;
	char *data;
	long mtime;
	long rdtime;
	Readcache *next;
};

static Readcache *rcache;

ulong
dirlen(char *s)
{
	Dir *d;
	ulong len;

	d = dirstat(s);
	if(d == nil)
		return 0;
	len = d->length;
	free(d);
	return len;
}

ulong
fsdirlen(CFsys *fs,char *s)
{
	Dir *d;
	ulong len;

	d = fsdirstat(fs,s);
	if(d == nil)
		return 0;
	len = d->length;
	free(d);
	return len;
}

ulong
dirmtime(char *s)
{
	Dir *d;
	ulong t;

	d = dirstat(s);
	if(d == nil)
		return 0;
	t = d->mtime;
	free(d);
	return t;
}

static char*
doreadfile(char *s)
{
	char *p;
	int fd, n;
	ulong len;

	len = dirlen(s);
	if(len == 0)
		return nil;

	p = malloc(len+1);
	if(p == nil)
		return nil;

	if((fd = open(s, OREAD)) < 0
	|| (n = readn(fd, p, len)) < 0) {
		close(fd);
		free(p);
		return nil;
	}

	p[n] = '\0';
	return p;
}

static char*
readfile(char *s)
{
	Readcache *r, **l;
	char *p;
	ulong mtime;

	for(l=&rcache, r=*l; r; l=&r->next, r=*l) {
		if(strcmp(r->file, s) != 0)
			continue;

		/*
		 * if it's less than 30 seconds since we read it, or it 
		 * hasn't changed, send back our copy
		 */
		if(time(0) - r->rdtime < 30)
			return strdup(r->data);
		if(dirmtime(s) == r->mtime) {
			r->rdtime = time(0);
			return strdup(r->data);
		}

		/* out of date, remove this and fall out of loop */
		*l = r->next;
		free(r->file);
		free(r->data);
		free(r);
		break;
	}

	/* add to cache */
	mtime = dirmtime(s);
	if(mtime == 0)
		return nil;

	if((p = doreadfile(s)) == nil)
		return nil;

	r = malloc(sizeof(*r));
	if(r == nil)
		return nil;
	r->mtime = mtime;
	r->file = estrdup(s);
	r->data = p;
	r->rdtime = time(0);
	r->next = rcache;
	rcache = r;
	return strdup(r->data);
}

static char*
translatedomain(char *dom, char *list)
{
	static char buf[200];
	char *p, *ep, *q, *nextp, *file;
	char *bbuf, *ebuf;
	Reprog *exp;

	if(dom == nil || *dom == 0)
		return nil;

	if(list == nil || (file = readfile(list)) == nil)
		return dom;

	for(p=file; p; p=nextp) {
		if(nextp = strchr(p, '\n'))
			*nextp++ = '\0';

		if(*p == '#' || (q = strpbrk(p, " \t")) == nil || q-p > sizeof(buf)-2)
			continue;

		bbuf = buf+1;
		ebuf = buf+(1+(q-p));
		strncpy(bbuf, p, ebuf-bbuf);
		*ebuf = 0;
		if(*bbuf != '^')
			*--bbuf = '^';
		if(ebuf[-1] != '$') {
			*ebuf++ = '$';
			*ebuf = 0;
		}

		if((exp = regcomp(bbuf)) == nil){
			fprint(2, "bad regexp in machinelist: %s\n", bbuf);
			killall("regexp");
		}

		if(regexec(exp, dom, 0, 0)){
			free(exp);
			ep = p+strlen(p);
			q += strspn(q, " \t");
			if(ep-q+2 > sizeof buf) {
				fprint(2, "huge replacement in machinelist: %.*s\n", utfnlen(q, ep-q), q);
				exits("bad big replacement");
			}
			strncpy(buf, q, ep-q);
			ebuf = buf+(ep-q);
			*ebuf = 0;
			while(ebuf > buf && (ebuf[-1] == ' ' || ebuf[-1] == '\t'))
				*--ebuf = 0;
			free(file);
			return buf;
		}
		free(exp);
	}
	free(file);

	return dom;
}

static char*
tryfindpicture(char *dom, char *user, char *dir, char *dict)
{
	static char buf[1024];
	char *file, *p, *nextp, *q;
	
	if((file = readfile(dict)) == nil)
		return nil;

	snprint(buf, sizeof buf, "%s/%s", dom, user);

	for(p=file; p; p=nextp){
		if(nextp = strchr(p, '\n'))
			*nextp++ = '\0';

		if(*p == '#' || (q = strpbrk(p, " \t")) == nil)
			continue;
		*q++ = 0;

		if(strcmp(buf, p) == 0){
			q += strspn(q, " \t");
			snprint(buf, sizeof buf, "%s/%s", dir, q);
			q = buf+strlen(buf);
			while(q > buf && (q[-1] == ' ' || q[-1] == '\t'))
				*--q = 0;
			free(file);
			return estrdup(buf);
		}
	}
	free(file);
	return nil;
}

static char*
estrstrdup(char *a, char *b)
{
	char *t;
	
	t = emalloc(strlen(a)+strlen(b)+1);
	strcpy(t, a);
	strcat(t, b);
	return t;
}

static char*
tryfindfiledir(char *dom, char *user, char *dir)
{
	char *dict, *ndir, *x, *odom;
	int fd;
	int i, n;
	Dir *d;
	
	/*
	 * If this directory has a .machinelist, use it.
	 */
	x = estrstrdup(dir, "/.machinelist");
	dom = estrdup(translatedomain(dom, x));
	free(x);
	/*
	 * If this directory has a .dict, use it.
	 */
	dict = estrstrdup(dir, "/.dict");
	if(access(dict, AEXIST) >= 0){
		x = tryfindpicture(dom, user, dir, dict);
		free(dict);
		free(dom);
		return x;
	}
	free(dict);
	
	/*
	 * If not, recurse into subdirectories.
	 * Ignore 48x48xN directories for now.
	 */
	if((fd = open(dir, OREAD)) < 0)
		return nil;
	while((n = dirread(fd, &d)) > 0){
		for(i=0; i<n; i++){
			if((d[i].mode&DMDIR)&& strncmp(d[i].name, "48x48x", 6) != 0){
				ndir = emalloc(strlen(dir)+1+strlen(d[i].name)+1);
				strcpy(ndir, dir);
				strcat(ndir, "/");
				strcat(ndir, d[i].name);
				if((x = tryfindfiledir(dom, user, ndir)) != nil){
					free(ndir);
					free(d);
					close(fd);
					free(dom);
					return x;
				}
			}
		}
		free(d);
	}
	close(fd);
	
	/*
	 * Handle 48x48xN directories in the right order.
	 */
	ndir = estrstrdup(dir, "/48x48x8");
	for(i=8; i>0; i>>=1){
		ndir[strlen(ndir)-1] = i+'0';
		if(access(ndir, AEXIST) >= 0 && (x = tryfindfiledir(dom, user, ndir)) != nil){
			free(ndir);
			free(dom);
			return x;
		}
	}
	free(ndir);
	free(dom);
	return nil;
}

static char*
tryfindfile(char *dom, char *user)
{
	char *p;

	while(dom && *dom){
		if(homeface && (p = tryfindfiledir(dom, user, homeface)) != nil)
			return p;
		if((p = tryfindfiledir(dom, user, libface)) != nil)
			return p;
		if((dom = strchr(dom, '.')) == nil)
			break;
		dom++;
	}
	return nil;
}

char*
findfile(Face *f, char *dom, char *user)
{
	char *p;

	if(facedom == nil){
		facedom = getenv("facedom");
		if(facedom == nil)
			facedom = DEFAULT;
	}
	if(libface == nil)
		libface = unsharp("#9/face");
	if(homeface == nil)
		homeface = smprint("%s/lib/face", getenv("HOME"));

	if(dom == nil)
		dom = facedom;

	f->unknown = 0;
	if((p = tryfindfile(dom, user)) != nil)
		return p;
	f->unknown = 1;
	p = tryfindfile(dom, "unknown");
	if(p != nil || strcmp(dom, facedom) == 0)
		return p;
	return tryfindfile("unknown", "unknown");
}

static
void
clearsaved(void)
{
	Facefile *f, *next, **lf;

	lf = &facefiles;
	for(f=facefiles; f!=nil; f=next){
		next = f->next;
		if(f->ref > 0){
			*lf = f;
			lf = &(f->next);
			continue;
		}
		if(f->image != display->black && f->image != display->white)
			freeimage(f->image);
		free(f->file);
		free(f);
	}
	*lf = nil;
	nsaved = 0;
}

void
freefacefile(Facefile *f)
{
	if(f==nil || f->ref-->1)
		return;
	if(++nsaved > Nsave)
		clearsaved();
}	

static Image*
myallocimage(ulong chan)
{
	Image *img;
	img = allocimage(display, Rect(0,0,Facesize,Facesize), chan, 0, DNofill);
	if(img == nil){
		clearsaved();
		img = allocimage(display, Rect(0,0,Facesize,Facesize), chan, 0, DNofill);
		if(img == nil)
			return nil;
	}
	return img;
}
		

static Image*
readbit(int fd, ulong chan)
{
	char buf[4096], hx[4], *p;
	uchar data[Facesize*Facesize];	/* more than enough */
	int nhx, i, n, ndata, nbit;
	Image *img;

	n = readn(fd, buf, sizeof buf);
	if(n <= 0)
		return nil;
	if(n >= sizeof buf)
		n = sizeof(buf)-1;
	buf[n] = '\0';

	n = 0;
	nhx = 0;
	nbit = chantodepth(chan);
	ndata = (Facesize*Facesize*nbit)/8;
	p = buf;
	while(n < ndata) {
		p = strpbrk(p+1, "0123456789abcdefABCDEF");
		if(p == nil)
			break;
		if(p[0] == '0' && p[1] == 'x')
			continue;

		hx[nhx] = *p;
		if(++nhx == 2) {
			hx[nhx] = 0;
			i = strtoul(hx, 0, 16);
			data[n++] = i;
			nhx = 0;
		}
	}
	if(n < ndata)
		return allocimage(display, Rect(0,0,Facesize,Facesize), CMAP8, 0, 0x88888888);

	img = myallocimage(chan);
	if(img == nil)
		return nil;
	loadimage(img, img->r, data, ndata);
	return img;
}

static Facefile*
readface(char *fn)
{
	int x, y, fd;
	uchar bits;
	uchar *p;
	Image *mask;
	Image *face;
	char buf[16];
	uchar data[Facesize*Facesize];
	uchar mdata[(Facesize*Facesize)/8];
	Facefile *f;
	Dir *d;

	for(f=facefiles; f!=nil; f=f->next){
		if(strcmp(fn, f->file) == 0){
			if(f->image == nil)
				break;
			if(time(0) - f->rdtime >= 30) {
				if(dirmtime(fn) != f->mtime){
					f = nil;
					break;
				}
				f->rdtime = time(0);
			}
			f->ref++;
			return f;
		}
	}

	if((fd = open(fn, OREAD)) < 0)
		return nil;

	if(readn(fd, buf, sizeof buf) != sizeof buf){
		close(fd);
		return nil;
	}

	seek(fd, 0, 0);

	mask = nil;
	if(buf[0] == '0' && buf[1] == 'x'){
		/* greyscale faces are just masks that we draw black through! */
		if(buf[2+8] == ',')	/* ldepth 1 */
			mask = readbit(fd, GREY2);
		else
			mask = readbit(fd, GREY1);
		face = display->black;
	}else{
		face = readimage(display, fd, 0);
		if(face == nil)
			goto Done;
		else if(face->chan == GREY4 || face->chan == GREY8){	/* greyscale: use inversion as mask */
			mask = myallocimage(face->chan);
			/* okay if mask is nil: that will copy the image white background and all */
			if(mask == nil)
				goto Done;

			/* invert greyscale image */
			draw(mask, mask->r, display->white, nil, ZP);
			gendraw(mask, mask->r, display->black, ZP, face, face->r.min);
			freeimage(face);
			face = display->black;
		}else if(face->depth == 8){	/* snarf the bytes back and do a fill. */
			mask = myallocimage(GREY1);
			if(mask == nil)
				goto Done;
			if(unloadimage(face, face->r, data, Facesize*Facesize) != Facesize*Facesize){	
				freeimage(mask);
				goto Done;
			}
			bits = 0;
			p = mdata;
			for(y=0; y<Facesize; y++){
				for(x=0; x<Facesize; x++){	
					bits <<= 1;
					if(data[Facesize*y+x] != 0xFF)
						bits |= 1;
					if((x&7) == 7)
						*p++ = bits&0xFF;
				}
			}
			if(loadimage(mask, mask->r, mdata, sizeof mdata) != sizeof mdata){
				freeimage(mask);
				goto Done;
			}
		}
	}

Done:
	/* always add at beginning of list, so updated files don't collide in cache */
	if(f == nil){
		f = emalloc(sizeof(Facefile));
		f->file = estrdup(fn);
		d = dirfstat(fd);
		if(d != nil){
			f->mtime = d->mtime;
			free(d);
		}
		f->next = facefiles;
		facefiles = f;
	}
	f->ref++;
	f->image = face;
	f->mask = mask;
	f->rdtime = time(0);
	close(fd);
	return f;
}

void
findbit(Face *f)
{
	char *fn;

	fn = findfile(f, f->str[Sdomain], f->str[Suser]);
	if(fn) {
		if(strstr(fn, "unknown"))
			f->unknown = 1;
		f->file = readface(fn);
	}
	if(f->file){
		f->bit = f->file->image;
		f->mask = f->file->mask;
	}else{
		/* if returns nil, this is still ok: draw(nil) works */
		f->bit = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DYellow);
		replclipr(f->bit, 1, Rect(0, 0, Facesize, Facesize));
		f->mask = nil;
	}
}
