#include <u.h>
#include <libc.h>
#include <bio.h>
#include "regexp.h"
#include "dfa.h"

/***
* Regular expression for matching.
*/

char *ignore[] =
{
       /* HTML that isn't A, IMG, or FONT */
       /* Must have a space somewhere to avoid catching <email@address> */
       "<[     \n\r]*("
               "[^aif]|"
               "a[^> \t\r\n]|"
               "i[^mM \t\r\n]|"
               "im[^gG \t\r\n]|"
               "img[^> \t\r\n]|"
               "f[^oO \t\r\n]|"
               "fo[^Nn \t\r\n]|"
               "fon[^tT \t\r\n]|"
               "font[^> \r\t\n]"
       ")[^>]*[ \t\n\r][^>]*>",
       "<[     \n\r]*("
               "i|im|f|fo|fon"
       ")[ \t\r\n][^>]*>",

       /* ignore html comments */
       "<!--([^\\-]|-[^\\-]|--[^>]|\n)*-->",

       /* random mail strings */
       "^message-id:.*\n([     ].*\n)*",
       "^in-reply-to:.*\n([    ].*\n)*",
       "^references:.*\n([     ].*\n)*",
       "^date:.*\n([   ].*\n)*",
       "^delivery-date:.*\n([  ].*\n)*",
       "e?smtp id .*",
       "^      id.*",
       "boundary=.*",
       "name=\"",
       "filename=\"",
       "news:<[^>]+>",
       "^--[^  ]*$",

       /* base64 encoding */
       "^[0-9a-zA-Z+\\-=/]+$",

       /* uu encoding */
       "^[!-Z]+$",

       /* little things */
       ".",
       "\n",
};

char *keywords[] =
{
       "([a-zA-Z'`$!¡-￿]|[0-9]([.,][0-9])*)+",
};

int debug;

Dreprog*
dregcomp(char *buf)
{
       Reprog *r;
       Dreprog *d;

       if(debug)
               print(">>> '%s'\n", buf);

       r = regcomp(buf);
       if(r == nil)
               sysfatal("regcomp");
       d = dregcvt(r);
       if(d == nil)
               sysfatal("dregcomp");
       free(r);
       return d;
}

char*
strcpycase(char *d, char *s)
{
       int cc, esc;

       cc = 0;
       esc = 0;
       while(*s){
               if(*s == '[')
                       cc++;
               if(*s == ']')
                       cc--;
               if(!cc && 'a' <= *s && *s <= 'z'){
                       *d++ = '[';
                       *d++ = *s;
                       *d++ = *s+'A'-'a';
                       *d++ = ']';
               }else
                       *d++ = *s;
               if(*s == '\\')
                       esc++;
               else if(esc)
                       esc--;
               s++;
       }
       return d;
}

void
regerror(char *msg)
{
       sysfatal("regerror: %s", msg);
}

void
buildre(Dreprog *re[3])
{
       int i;
       static char buf[16384], *s;

       re[0] = dregcomp("^From ");

       s = buf;
       for(i=0; i<nelem(keywords); i++){
               if(i != 0)
                       *s++ = '|';
               s = strcpycase(s, keywords[i]);
       }
       *s = 0;
       re[1] = dregcomp(buf);

       s = buf;
       for(i=0; i<nelem(ignore); i++){
               if(i != 0)
                       *s++ = '|';
               s = strcpycase(s, ignore[i]);
       }
       *s = 0;
       re[2] = dregcomp(buf);
}

void
usage(void)
{
       fprint(2, "usage: regen [-d]\n");
       exits("usage");
}

void
main(int argc, char **argv)
{
       Dreprog *re[3];
       Biobuf b;

       ARGBEGIN{
       default:
               usage();
       case 'd':
               debug = 1;
       }ARGEND

       if(argc != 0)
               usage();

       buildre(re);
       Binit(&b, 1, OWRITE);
       Bprintdfa(&b, re[0]);
       Bprintdfa(&b, re[1]);
       Bprintdfa(&b, re[2]);
       exits(0);
}