#include <u.h>
#include <libc.h>
#include <bio.h>
#include <regexp.h>
#include <thread.h>
#include <ctype.h>
#include <plumb.h>
#include "plumber.h"

typedef struct Input Input;
typedef struct Var Var;

struct Input
{
	char		*file;		/* name of file */
	Biobuf	*fd;		/* input buffer, if from real file */
	uchar	*s;		/* input string, if from /mnt/plumb/rules */
	uchar	*end;	/* end of input string */
	int		lineno;
	Input	*next;	/* file to read after EOF on this one */
};

struct Var
{
	char	*name;
	char	*value;
	char *qvalue;
};

static int		parsing;
static int		nvars;
static Var		*vars;
static Input	*input;

static char 	ebuf[4096];

char *badports[] =
{
	".",
	"..",
	"send",
	nil
};

char *objects[] =
{
	"arg",
	"attr",
	"data",
	"dst",
	"plumb",
	"src",
	"type",
	"wdir",
	nil
};

char *verbs[] =
{
	"add",
	"client",
	"delete",
	"is",
	"isdir",
	"isfile",
	"matches",
	"set",
	"start",
	"to",
	nil
};

static void
printinputstackrev(Input *in)
{
	if(in == nil)
		return;
	printinputstackrev(in->next);
	fprint(2, "%s:%d: ", in->file, in->lineno);
}

void
printinputstack(void)
{
	printinputstackrev(input);
}

static void
pushinput(char *name, int fd, uchar *str)
{
	Input *in;
	int depth;

	depth = 0;
	for(in=input; in; in=in->next)
		if(depth++ >= 10)	/* prevent deep C stack in plumber and bad include structure */
			parseerror("include stack too deep; max 10");

	in = emalloc(sizeof(Input));
	in->file = estrdup(name);
	in->next = input;
	input = in;
	if(str)
		in->s = str;
	else{
		in->fd = emalloc(sizeof(Biobuf));
		if(Binit(in->fd, fd, OREAD) < 0)
			parseerror("can't initialize Bio for rules file: %r");
	}

}

int
popinput(void)
{
	Input *in;

	in = input;
	if(in == nil)
		return 0;
	input = in->next;
	if(in->fd){
		Bterm(in->fd);
		free(in->fd);
	}
	free(in);
	return 1;
}

int
getc(void)
{
	if(input == nil)
		return Beof;
	if(input->fd)
		return Bgetc(input->fd);
	if(input->s < input->end)
		return *(input->s)++;
	return -1;
}

char*
getline(void)
{
	static int n = 0;
	static char *s /*, *incl*/;
	int c, i;

	i = 0;
	for(;;){
		c = getc();
		if(c < 0)
			return nil;
		if(i == n){
			n += 100;
			s = erealloc(s, n);
		}
		if(c<0 || c=='\0' || c=='\n')
			break;
		s[i++] = c;
	}
	s[i] = '\0';
	return s;
}

int
lookup(char *s, char *tab[])
{
	int i;

	for(i=0; tab[i]!=nil; i++)
		if(strcmp(s, tab[i])==0)
			return i;
	return -1;
}

Var*
lookupvariable(char *s, int n)
{
	int i;

	for(i=0; i<nvars; i++)
		if(n==strlen(vars[i].name) && memcmp(s, vars[i].name, n)==0)
			return vars+i;
	return nil;
}

char*
variable(char *s, int n)
{
	Var *var;

	var = lookupvariable(s, n);
	if(var)
		return var->qvalue;
	return nil;
}

void
setvariable(char  *s, int n, char *val, char *qval)
{
	Var *var;

	var = lookupvariable(s, n);
	if(var){
		free(var->value);
		free(var->qvalue);
	}else{
		vars = erealloc(vars, (nvars+1)*sizeof(Var));
		var = vars+nvars++;
		var->name = emalloc(n+1);
		memmove(var->name, s, n);
	}
	var->value = estrdup(val);
	var->qvalue = estrdup(qval);
}

static char*
nonnil(char *s)
{
	if(s == nil)
		return "";
	return s;
}

static char*
filename(Exec *e, char *name)
{
	static char *buf;	/* rock to hold value so we don't leak the strings */

	free(buf);
	/* if name is defined, used it */
	if(name!=nil && name[0]!='\0'){
		buf = estrdup(name);
		return cleanname(buf);
	}
	/* if data is an absolute file name, or wdir is empty, use it */
	if(e->msg->data[0]=='/' || e->msg->wdir==nil || e->msg->wdir[0]=='\0'){
		buf = estrdup(e->msg->data);
		return cleanname(buf);
	}
	buf = emalloc(strlen(e->msg->wdir)+1+strlen(e->msg->data)+1);
	sprint(buf, "%s/%s", e->msg->wdir, e->msg->data);
	return cleanname(buf);
}

char*
dollar(Exec *e, char *s, int *namelen)
{
	int n;
	static char *abuf;
	char *t;

	*namelen = 1;
	if(e!=nil && '0'<=s[0] && s[0]<='9')
		return nonnil(e->match[s[0]-'0']);

	for(t=s; isalnum(*t); t++)
		;
	n = t-s;
	*namelen = n;

	if(e != nil){
		if(n == 3){
			if(memcmp(s, "src", 3) == 0)
				return nonnil(e->msg->src);
			if(memcmp(s, "dst", 3) == 0)
				return nonnil(e->msg->dst);
			if(memcmp(s, "dir", 3) == 0)
				return filename(e, e->dir);
		}
		if(n == 4){
			if(memcmp(s, "attr", 4) == 0){
				free(abuf);
				abuf = plumbpackattr(e->msg->attr);
				return nonnil(abuf);
			}
			if(memcmp(s, "data", 4) == 0)
				return nonnil(e->msg->data);
			if(memcmp(s, "file", 4) == 0)
				return filename(e, e->file);
			if(memcmp(s, "type", 4) == 0)
				return nonnil(e->msg->type);
			if(memcmp(s, "wdir", 3) == 0)
				return nonnil(e->msg->wdir);
		}
	}

	return variable(s, n);
}

/* expand one blank-terminated string, processing quotes and $ signs */
char*
expand(Exec *e, char *s, char **ends)
{
	char *p, *ep, *val;
	int namelen, quoting;

	p = ebuf;
	ep = ebuf+sizeof ebuf-1;
	quoting = 0;
	while(p<ep && *s!='\0' && (quoting || (*s!=' ' && *s!='\t'))){
		if(*s == '\''){
			s++;
			if(!quoting)
				quoting = 1;
			else  if(*s == '\''){
				*p++ = '\'';
				s++;
			}else
				quoting = 0;
			continue;
		}
		if(quoting || *s!='$'){
			*p++ = *s++;
			continue;
		}
		s++;
		val = dollar(e, s, &namelen);
		if(val == nil){
			*p++ = '$';
			continue;
		}
		if(ep-p < strlen(val))
			return "string-too-long";
		strcpy(p, val);
		p += strlen(val);
		s += namelen;
	}
	if(ends)
		*ends = s;
	*p = '\0';
	return ebuf;
}

void
regerror(char *msg)
{
	if(parsing){
		parsing = 0;
		parseerror("%s", msg);
	}
	error("%s", msg);
}

void
parserule(Rule *r)
{
	r->qarg = estrdup(expand(nil, r->arg, nil));
	switch(r->obj){
	case OArg:
	case OAttr:
	case OData:
	case ODst:
	case OType:
	case OWdir:
	case OSrc:
		if(r->verb==VClient || r->verb==VStart || r->verb==VTo)
			parseerror("%s not valid verb for object %s", verbs[r->verb], objects[r->obj]);
		if(r->obj!=OAttr && (r->verb==VAdd || r->verb==VDelete))
			parseerror("%s not valid verb for object %s", verbs[r->verb], objects[r->obj]);
		if(r->verb == VMatches){
			r->regex = regcomp(r->qarg);
			return;
		}
		break;
	case OPlumb:
		if(r->verb!=VClient && r->verb!=VStart && r->verb!=VTo)
			parseerror("%s not valid verb for object %s", verbs[r->verb], objects[r->obj]);
		break;
	}
}

int
assignment(char *p)
{
	char *var, *qval;
	int n;

	if(!isalpha(p[0]))
		return 0;
	for(var=p; isalnum(*p); p++)
		;
	n = p-var;
	while(*p==' ' || *p=='\t')
			p++;
	if(*p++ != '=')
		return 0;
	while(*p==' ' || *p=='\t')
			p++;
	qval = expand(nil, p, nil);
	setvariable(var, n, p, qval);
	return 1;
}

int
include(char *s)
{
	char *t, *args[3], buf[128];
	int n, fd;

	if(strncmp(s, "include", 7) != 0)
		return 0;
	/* either an include or an error */
	n = tokenize(s, args, nelem(args));
	if(n < 2)
		goto Err;
	if(strcmp(args[0], "include") != 0)
		goto Err;
	if(args[1][0] == '#')
		goto Err;
	if(n>2 && args[2][0] != '#')
		goto Err;
	t = args[1];
	fd = open(t, OREAD);
	if(fd<0 && t[0]!='/' && strncmp(t, "./", 2)!=0 && strncmp(t, "../", 3)!=0){
		snprint(buf, sizeof buf, "#9/plumb/%s", t);
		t = buf;
		fd = open(t, OREAD);
	}
	if(fd < 0)
		parseerror("can't open %s for inclusion", t);
	pushinput(t, fd, nil);
	return 1;

    Err:
	parseerror("malformed include statement");
	return 0;
}

Rule*
readrule(int *eof)
{
	Rule *rp;
	char *line, *p;
	char *word;

Top:
	line = getline();
	if(line == nil){
		/*
		 * if input is from string, and bytes remain (input->end is within string),
		 * morerules() will pop input and save remaining data.  otherwise pop
		 * the stack here, and if there's more input, keep reading.
		 */
		if((input!=nil && input->end==nil) && popinput())
			goto Top;
		*eof = 1;
		return nil;
	}
	input->lineno++;

	for(p=line; *p==' ' || *p=='\t'; p++)
		;
	if(*p=='\0' || *p=='#')	/* empty or comment line */
		return nil;

	if(include(p))
		goto Top;

	if(assignment(p))
		return nil;

	rp = emalloc(sizeof(Rule));

	/* object */
	for(word=p; *p!=' ' && *p!='\t'; p++)
		if(*p == '\0')
			parseerror("malformed rule");
	*p++ = '\0';
	rp->obj = lookup(word, objects);
	if(rp->obj < 0){
		if(strcmp(word, "kind") == 0)	/* backwards compatibility */
			rp->obj = OType;
		else
			parseerror("unknown object %s", word);
	}

	/* verb */
	while(*p==' ' || *p=='\t')
		p++;
	for(word=p; *p!=' ' && *p!='\t'; p++)
		if(*p == '\0')
			parseerror("malformed rule");
	*p++ = '\0';
	rp->verb = lookup(word, verbs);
	if(rp->verb < 0)
		parseerror("unknown verb %s", word);

	/* argument */
	while(*p==' ' || *p=='\t')
		p++;
	if(*p == '\0')
		parseerror("malformed rule");
	rp->arg = estrdup(p);

	parserule(rp);

	return rp;
}

void
freerule(Rule *r)
{
	free(r->arg);
	free(r->qarg);
	free(r->regex);
}

void
freerules(Rule **r)
{
	while(*r)
		freerule(*r++);
}

void
freeruleset(Ruleset *rs)
{
	freerules(rs->pat);
	free(rs->pat);
	freerules(rs->act);
	free(rs->act);
	free(rs->port);
	free(rs);
}

Ruleset*
readruleset(void)
{
	Ruleset *rs;
	Rule *r;
	int eof, inrule, i, ncmd;

   Again:
	eof = 0;
	rs = emalloc(sizeof(Ruleset));
	rs->pat = emalloc(sizeof(Rule*));
	rs->act = emalloc(sizeof(Rule*));
	inrule = 0;
	ncmd = 0;
	for(;;){
		r = readrule(&eof);
		if(eof)
			break;
		if(r==nil){
			if(inrule)
				break;
			continue;
		}
		inrule = 1;
		switch(r->obj){
		case OArg:
		case OAttr:
		case OData:
		case ODst:
		case OType:
		case OWdir:
		case OSrc:
			rs->npat++;
			rs->pat = erealloc(rs->pat, (rs->npat+1)*sizeof(Rule*));
			rs->pat[rs->npat-1] = r;
			rs->pat[rs->npat] = nil;
			break;
		case OPlumb:
			rs->nact++;
			rs->act = erealloc(rs->act, (rs->nact+1)*sizeof(Rule*));
			rs->act[rs->nact-1] = r;
			rs->act[rs->nact] = nil;
			if(r->verb == VTo){
				if(rs->npat>0 && rs->port != nil)	/* npat==0 implies port declaration */
					parseerror("too many ports");
				if(lookup(r->qarg, badports) >= 0)
					parseerror("illegal port name %s", r->qarg);
				rs->port = estrdup(r->qarg);
			}else
				ncmd++;	/* start or client rule */
			break;
		}
	}
	if(ncmd > 1){
		freeruleset(rs);
		parseerror("ruleset has more than one client or start action");
	}
	if(rs->npat>0 && rs->nact>0)
		return rs;
	if(rs->npat==0 && rs->nact==0){
		freeruleset(rs);
		return nil;
	}
	if(rs->nact==0 || rs->port==nil){
		freeruleset(rs);
		parseerror("ruleset must have patterns and actions");
		return nil;
	}

	/* declare ports */
	for(i=0; i<rs->nact; i++)
		if(rs->act[i]->verb != VTo){
			freeruleset(rs);
			parseerror("ruleset must have actions");
			return nil;
		}
	for(i=0; i<rs->nact; i++)
		addport(rs->act[i]->qarg);
	freeruleset(rs);
	goto Again;
}

Ruleset**
readrules(char *name, int fd)
{
	Ruleset *rs, **rules;
	int n;

	parsing = 1;
	pushinput(name, fd, nil);
	rules = emalloc(sizeof(Ruleset*));
	for(n=0; (rs=readruleset())!=nil; n++){
		rules = erealloc(rules, (n+2)*sizeof(Ruleset*));
		rules[n] = rs;
		rules[n+1] = nil;
	}
	popinput();
	parsing = 0;
	return rules;
}

char*
concat(char *s, char *t)
{
	if(t == nil)
		return s;
	if(s == nil)
		s = estrdup(t);
	else{
		s = erealloc(s, strlen(s)+strlen(t)+1);
		strcat(s, t);
	}
	return s;
}

char*
printpat(Rule *r)
{
	char *s;

	s = emalloc(strlen(objects[r->obj])+1+strlen(verbs[r->verb])+1+strlen(r->arg)+1+1);
	sprint(s, "%s\t%s\t%s\n", objects[r->obj], verbs[r->verb], r->arg);
	return s;
}

char*
printvar(Var *v)
{
	char *s;

	s = emalloc(strlen(v->name)+1+strlen(v->value)+2+1);
	sprint(s, "%s=%s\n\n", v->name, v->value);
	return s;
}

char*
printrule(Ruleset *r)
{
	int i;
	char *s;

	s = nil;
	for(i=0; i<r->npat; i++)
		s = concat(s, printpat(r->pat[i]));
	for(i=0; i<r->nact; i++)
		s = concat(s, printpat(r->act[i]));
	s = concat(s, "\n");
	return s;
}

char*
printport(char *port)
{
	char *s;

	s = nil;
	s = concat(s, "plumb to ");
	s = concat(s, port);
	s = concat(s, "\n");
	return s;
}

char*
printrules(void)
{
	int i;
	char *s;

	s = nil;
	for(i=0; i<nvars; i++)
		s = concat(s, printvar(&vars[i]));
	for(i=0; i<nports; i++)
		s = concat(s, printport(ports[i]));
	s = concat(s, "\n");
	for(i=0; rules[i]; i++)
		s = concat(s, printrule(rules[i]));
	return s;
}

char*
stringof(char *s, int n)
{
	char *t;

	t = emalloc(n+1);
	memmove(t, s, n);
	return t;
}

uchar*
morerules(uchar *text, int done)
{
	int n;
	Ruleset *rs;
	uchar *otext, *s, *endofrule;

	pushinput("<rules input>", -1, text);
	if(done)
		input->end = text+strlen((char*)text);
	else{
		/*
		 * Help user by sending any full rules to parser so any parse errors will
		 * occur on write rather than close. A heuristic will do: blank line ends rule.
		 */
		endofrule = nil;
		for(s=text; *s!='\0'; s++)
			if(*s=='\n' && *++s=='\n')
				endofrule = s+1;
		if(endofrule == nil)
			return text;
		input->end = endofrule;
	}
	for(n=0; rules[n]; n++)
		;
	while((rs=readruleset()) != nil){
		rules = erealloc(rules, (n+2)*sizeof(Ruleset*));
		rules[n++] = rs;
		rules[n] = nil;
	}
	otext =text;
	if(input == nil)
		text = (uchar*)estrdup("");
	else
		text = (uchar*)estrdup((char*)input->end);
	popinput();
	free(otext);
	return text;
}

char*
writerules(char *s, int n)
{
	static uchar *text;
	char *tmp;

	free(lasterror);
	lasterror = nil;
	parsing = 1;
	if(setjmp(parsejmp) == 0){
		tmp = stringof(s, n);
		text = (uchar*)concat((char*)text, tmp);
		free(tmp);
		text = morerules(text, s==nil);
	}
	if(s == nil){
		free(text);
		text = nil;
	}
	parsing = 0;
	makeports(rules);
	return lasterror;
}
