#include <u.h>
#include <libc.h>
#include <ctype.h>
#include "getflags.h"

char **flag[NFLAG];
char cmdline[NCMDLINE+1];
char *cmdname;
char *flagset[];
char *flagset[]={"<flag>"};
static char *flagarg="";
static void reverse(char **, char **);
static int scanflag(int, char *);
static int reason;
#define	RESET	1
#define	ARGCCOUNT	2
#define	FLAGSYN	3
#define	BADFLAG	4
static int badflag;
char *getflagsargv[NGETFLAGSARGV+2];	/* original argv stored here for people who need it */

int
getflags(int argc, char *argv[], char *flags)
{
	char *s, *t;
	int i, j, c, count;
	flagarg=flags;
	if(cmdname==0){
		cmdname=argv[0];
		for(i=0;i!=argc && i!=NGETFLAGSARGV;i++) getflagsargv[i]=argv[i];
		if(argc>NGETFLAGSARGV) getflagsargv[i++]="...";
		getflagsargv[i]=0;
	}
	s=cmdline;
	for(i=0;i!=argc;i++){
		for(t=argv[i];*t;)
			if(s!=&cmdline[NCMDLINE])
				*s++=*t++;
			else
				break;
		if(i!=argc-1 && s!=&cmdline[NCMDLINE])
			*s++=' ';
	}
	*s='\0';
	i=1;
	while(i!=argc && argv[i][0]=='-'){
		s=argv[i]+1;
		if(*s=='\0'){	/* if argument is "-", stop scanning and delete it */
			for(j=i+1;j<=argc;j++)
				argv[j-1]=argv[j];
			return argc-1;
		}
		while(*s){
			c=*s++;
			count=scanflag(c, flags);
			if(count==-1) return -1;
			if(flag[c]){ reason=RESET; badflag=c; return -1; }
			if(count==0){
				flag[c]=flagset;
				if(*s=='\0'){
					for(j=i+1;j<=argc;j++)
						argv[j-1]=argv[j];
					--argc;
				}
			}
			else{
				if(*s=='\0'){
					for(j=i+1;j<=argc;j++)
						argv[j-1]=argv[j];
					--argc;
					s=argv[i];
				}
				if(argc-i<count){
					reason=ARGCCOUNT;
					badflag=c;
					return -1;
				}
				reverse(argv+i, argv+argc);
				reverse(argv+i, argv+argc-count);
				reverse(argv+argc-count+1, argv+argc);
				argc-=count;
				flag[c]=argv+argc+1;
				flag[c][0]=s;
				s="";
			}
		}
	}
	return argc;
}

void
static reverse(char **p, char **q)
{
	register char *t;
	for(;p<q;p++,--q){ t=*p; *p=*q; *q=t; }
}

static int
scanflag(int c, char *f)
{
	int fc, count;
	if(0<=c && c<NFLAG) while(*f){
		if(*f==' '){
			f++;
			continue;
		}
		fc=*f++;
		if(*f==':'){
			f++;
			if(!isdigit((uchar)*f)){ reason=FLAGSYN; return -1; }
			count=strtol(f, &f, 10);
		}
		else
			count=0;
		if(*f=='['){
			int depth=1;
			do{
				f++;
				if(*f=='\0'){ reason=FLAGSYN; return -1; }
				if(*f=='[') depth++;
				if(*f==']') depth--;
			}while(depth>0);
			f++;
		}
		if(c==fc) return count;
	}
	reason=BADFLAG;
	badflag=c;
	return -1;
}

static void errn(char *, int), errs(char *), errc(int);

void
usage(char *tail)
{
	char *s, *t, c;
	int count, nflag=0;
	switch(reason){
	case RESET:
		errs("Flag -");
		errc(badflag);
		errs(": set twice\n");
		break;
	case ARGCCOUNT:
		errs("Flag -");
		errc(badflag);
		errs(": too few arguments\n");
		break;
	case FLAGSYN:
		errs("Bad argument to getflags!\n");
		break;
	case BADFLAG:
		errs("Illegal flag -");
		errc(badflag);
		errc('\n');
		break;
	}
	errs("Usage: ");
	errs(cmdname);
	for(s=flagarg;*s;){
		c=*s;
		if(*s++==' ') continue;
		if(*s==':'){
			s++;
			count=strtol(s, &s, 10);
		}
		else count=0;
		if(count==0){
			if(nflag==0) errs(" [-");
			nflag++;
			errc(c);
		}
		if(*s=='['){
			int depth=1;
			s++;
			for(;*s!='\0' && depth>0; s++)
				if (*s==']') depth--;
				else if (*s=='[') depth++;
		}
	}
	if(nflag) errs("]");
	for(s=flagarg;*s;){
		c=*s;
		if(*s++==' ') continue;
		if(*s==':'){
			s++;
			count=strtol(s, &s, 10);
		}
		else count=0;
		if(count!=0){
			errs(" [-");
			errc(c);
			if(*s=='['){
				int depth=1;
				s++;
				t=s;
				for(;*s!='\0' && depth>0; s++)
					if (*s==']') depth--;
					else if (*s=='[') depth++;
				errs(" ");
				errn(t, s-t);
			}
			else
				while(count--) errs(" arg");
			errs("]");
		}
		else if(*s=='['){
			int depth=1;
			s++;
			for(;*s!='\0' && depth>0; s++)
				if (*s==']') depth--;
				else if (*s=='[') depth++;
		}
	}
	if(tail){
		errs(" ");
		errs(tail);
	}
	errs("\n");
	exits("usage");
}

static void
errn(char *s, int count)
{
	while(count){ errc(*s++); --count; }
}

static void
errs(char *s)
{
	while(*s) errc(*s++);
}

#define	NBUF	80
static char buf[NBUF], *bufp=buf;

static void
errc(int c){
	*bufp++=c;
	if(bufp==&buf[NBUF] || c=='\n'){
		write(2, buf, bufp-buf);
		bufp=buf;
	}
}

#ifdef TEST
#include <stdio.h>
main(int argc, char *argv[])
{
	int c, i, n;
	if(argc<3){
		fprint(2, "Usage: %s flags cmd ...\n", argv[0]);
		exits("usage");
	}
	n=getflags(argc-2, argv+2, argv[1]);
	if(n<0) usage("...");
	putchar('\n');
	for(c=0;c!=128;c++) if(flag[c]){
		print("\t-.%c. ", c);
		n=scanflag(c, argv[1]);
		for(i=0;i!=n;i++) print(" <%s>", flag[c][i]);
		putchar('\n');
	}
}
#endif
