/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "apr.h"
#include "apr_lib.h"
#include "apr_pools.h"
#include "apr_strings.h"
#include "ap_config.h"
#include "ap_regex.h"
#include "httpd.h"

static apr_status_t rxplus_cleanup(void *preg)
{
    ap_regfree((ap_regex_t *) preg);
    return APR_SUCCESS;
}

AP_DECLARE(ap_rxplus_t*) ap_rxplus_compile(apr_pool_t *pool,
                                           const char *pattern)
{
    /* perl style patterns
     * add support for more as and when wanted
     * substitute: s/rx/subs/
     * match: m/rx/ or just /rx/
     */

    /* allow any nonalnum delimiter as first or second char.
     * If we ever use this with non-string pattern we'll need an extra check
     */
    const char *endp = 0;
    const char *str = pattern;
    const char *rxstr;
    ap_rxplus_t *ret = apr_pcalloc(pool, sizeof(ap_rxplus_t));
    char delim = 0;
    enum { SUBSTITUTE = 's', MATCH = 'm'} action = MATCH;

    if (!apr_isalnum(pattern[0])) {
        delim = *str++;
    }
    else if (pattern[0] == 's' && !apr_isalnum(pattern[1])) {
        action = SUBSTITUTE;
        delim = pattern[1];
        str += 2;
    }
    else if (pattern[0] == 'm' && !apr_isalnum(pattern[1])) {
        delim = pattern[1];
        str += 2;
    }
    /* TODO: support perl's after/before */
    /* FIXME: fix these simplminded delims */

    /* we think there's a delimiter.  Allow for it not to be if unmatched */
    if (delim) {
        endp = ap_strchr_c(str, delim);
    }
    if (!endp) { /* there's no delim or flags */
        if (ap_regcomp(&ret->rx, pattern, 0) == 0) {
            apr_pool_cleanup_register(pool, &ret->rx, rxplus_cleanup,
                                      apr_pool_cleanup_null);
            return ret;
        }
        else {
            return NULL;
        }
    }

    /* We have a delimiter.  Use it to extract the regexp */
    rxstr = apr_pstrmemdup(pool, str, endp-str);

    /* If it's a substitution, we need the replacement string
     * TODO: possible future enhancement - support other parsing
     * in the replacement string.
     */
    if (action == SUBSTITUTE) {
        str = endp+1;
        if (!*str || (endp = ap_strchr_c(str, delim), !endp)) {
            /* missing replacement string is an error */
            return NULL;
        }
        ret->subs = apr_pstrmemdup(pool, str, endp-str);
    }

    /* anything after the current delimiter is flags */
    ret->flags = ap_regcomp_get_default_cflags() & AP_REG_DOLLAR_ENDONLY;
    while (*++endp) {
        switch (*endp) {
        case 'i': ret->flags |= AP_REG_ICASE; break;
        case 'm': ret->flags |= AP_REG_NEWLINE; break;
        case 'n': ret->flags |= AP_REG_NOMEM; break;
        case 'g': ret->flags |= AP_REG_MULTI; break;
        case 's': ret->flags |= AP_REG_DOTALL; break;
        case '^': ret->flags |= AP_REG_NOTBOL; break;
        case '$': ret->flags |= AP_REG_NOTEOL; break;
        default: break; /* we should probably be stricter here */
        }
    }
    if (ap_regcomp(&ret->rx, rxstr, AP_REG_NO_DEFAULT | ret->flags) == 0) {
        apr_pool_cleanup_register(pool, &ret->rx, rxplus_cleanup,
                                  apr_pool_cleanup_null);
    }
    else {
        return NULL;
    }
    if (!(ret->flags & AP_REG_NOMEM)) {
        /* count size of memory required, starting at 1 for the whole-match
         * Simpleminded should be fine 'cos regcomp already checked syntax
         */
        ret->nmatch = 1;
        while (*rxstr) {
            switch (*rxstr++) {
            case '\\':  /* next char is escaped - skip it */
                if (*rxstr != 0) {
                    ++rxstr;
                }
                break;
            case '(':   /* unescaped bracket implies memory */
                ++ret->nmatch;
                break;
            default:
                break;
            }
        }
        ret->pmatch = apr_palloc(pool, ret->nmatch*sizeof(ap_regmatch_t));
    }
    return ret;
}

AP_DECLARE(int) ap_rxplus_exec(apr_pool_t *pool, ap_rxplus_t *rx,
                               const char *pattern, char **newpattern)
{
    int ret = 1;
    int startl, oldl, newl, diffsz;
    const char *remainder;
    char *subs;
/* snrf process_regexp from mod_headers */
    if (ap_regexec(&rx->rx, pattern, rx->nmatch, rx->pmatch, rx->flags) != 0) {
        rx->match = NULL;
        return 0; /* no match, nothing to do */
    }
    rx->match = pattern;
    if (rx->subs) {
        *newpattern = ap_pregsub(pool, rx->subs, pattern,
                                 rx->nmatch, rx->pmatch);
        if (!*newpattern) {
            return 0; /* FIXME - should we do more to handle error? */
        }
        startl = rx->pmatch[0].rm_so;
        oldl = rx->pmatch[0].rm_eo - startl;
        newl = strlen(*newpattern);
        diffsz = newl - oldl;
        remainder = pattern + startl + oldl;
        if (rx->flags & AP_REG_MULTI) {
            /* recurse to do any further matches */
            ret += ap_rxplus_exec(pool, rx, remainder, &subs);
            if (ret > 1) {
                /* a further substitution happened */
                diffsz += strlen(subs) - strlen(remainder);
                remainder = subs;
            }
        }
        subs  = apr_palloc(pool, strlen(pattern) + 1 + diffsz);
        memcpy(subs, pattern, startl);
        memcpy(subs+startl, *newpattern, newl);
        strcpy(subs+startl+newl, remainder);
        *newpattern = subs;
    }
    return ret;
}
#ifdef DOXYGEN
AP_DECLARE(int) ap_rxplus_nmatch(ap_rxplus_t *rx)
{
    return (rx->match != NULL) ? rx->nmatch : 0;
}
#endif

/* If this blows up on you, see the notes in the header/apidoc
 * rx->match is a pointer and it's your responsibility to ensure
 * it hasn't gone out-of-scope since the last ap_rxplus_exec
 */
AP_DECLARE(void) ap_rxplus_match(ap_rxplus_t *rx, int n, int *len,
                                 const char **match)
{
    if (n >= 0 && n < ap_rxplus_nmatch(rx)) {
        *match = rx->match + rx->pmatch[n].rm_so;
        *len = rx->pmatch[n].rm_eo - rx->pmatch[n].rm_so;
    }
    else {
        *len = -1;
        *match = NULL;
    }
}
AP_DECLARE(char*) ap_rxplus_pmatch(apr_pool_t *pool, ap_rxplus_t *rx, int n)
{
    int len;
    const char *match;
    ap_rxplus_match(rx, n, &len, &match);
    return apr_pstrndup(pool, match, len);
}
