#include <stdio.h>
#include <string.h>
#include <regex.h>

#include "safestring.h"
#include "util.h"
#include "clog.h"

bool reg_match( const char * input, const char * regexp, char * ret, int sz, int * pos /*= NULL*/ )
{
        regex_t compiled;
        regmatch_t match[2];

        bool satisfied = false;
        if ( ret ) ret[0] = 0;

//      logfmt( FLOG_MAX,  "Matching '%s' against '%s'", input, regexp );

        if ( regcomp( &compiled, regexp, REG_EXTENDED ) != 0 )
        {
                logfmt( logWARNING, "regcomp returned non-0, assuming a match" );
        }
        else
        {
                size_t r = regexec( &compiled, input, 2, match, 0 );

                if ( r==0 )     // match
                {
                    if ( pos )
                        *pos = match[1].rm_so;

                    int len = match[1].rm_eo-match[1].rm_so;

                 if ( ret )
                        strnsafecpy( ret, &input[ match[1].rm_so ],  len, sz );

                    satisfied = true;
                }
                else
                    satisfied = false;

                regfree( &compiled );
        }
        return satisfied;
}


char * urlencode( const char * buf, char * text, int sz )
{
// old  char url[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ^_\\-0123456789.";    // .  ???
        char url[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$-_.!*'(),";        // $-_.+!*'(),  took '+' out
        int len = strlen(buf);
//      fprintf(flog, "buf: '%s', len: %d\n", buf, len); fflush(flog);
        text[0] = 0;
        for (int i=0; i<len; i++)
        {
                int len = strlen(text);

                if (strchr(url, buf[i]))
                        snprintf(&text[len], sz-len, "%c", buf[i]);
                else
                        snprintf(&text[len], sz-len, "%%%02x", (unsigned char)buf[i]);
//              fprintf(flog, "%d\n", i); fflush(flog);
        }
//      strcpy(buf, text);
//      Log(text, "Returning:");
        return text;
}


/*
char * urlencode(const char * buf)
{
        return urlencode( buf, text, sizeof(text) );
}
*/

char * urldecode( char * buf, char * text, int sz)
{
//      Log(buf, "urldecode()");
    unsigned int c3;
    char * c2; c2 = buf;
    unsigned int ch;
    char * value=text;
//    int valuelen = sz;

    value[0] = 0;
    //bool EOS = false;

    while (c2)
    {
                c3 = strcspn(c2, "%+");  // "%+"
                if (c3==strlen(c2))
                {
//                      strncpy_(&value[strlen(value)], c2, Min0(c3, valuelen-strlen(value)-1, EOS) );
                        strsafecat( value, c2, sz );
                        break; //over
                }

//              strncpy_(&value[strlen(value)], c2, Min0(c3, valuelen-strlen(value)-1, EOS) );
                strnsafecat( value, c2, c3, sz );

        //      Log(value);
//              if (EOS) break;


                // '+' is actually an allowed symbol per http://www.rfc-editor.org/rfc/rfc1738.txt
                // but browser rules say space is encoded as '+'
                //      http://www.speakeasy.org/~cgires/readdata/

                if (*(c2+c3)=='+')
                {
//                      strncpy_(&value[strlen(value)], " ", Min0(1, valuelen-strlen(value)-1, EOS) );
                        strsafecat( value, " ", sz );
//                      if (EOS) break;
                        c2+=c3+1;
                }
                else
                {
                        sscanf(c2+c3+1, "%2x", &ch);
                        strcatf( value, sz, "%c", ch);

//                      if (strlen(value)>=valuelen-1)
//                              { EOS = TRUE; break; }

                        c2+=c3+3;
                 }
    }

        value[sz-1] = 0;

//      Log(text, "urldecode returning");
    return text;
}

