/*
 * Copyright (c) 2005, 2008 Sun Microsystems, Inc. All Rights Reserved.
 * Use is subject to license terms.
 *
 * Licensed 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 "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include "apr_strings.h"
#include "apr_general.h"
#include "util_filter.h"
#include "apr_buckets.h"
#include "http_request.h"
#include "libsed.h"

static const char *sed_filter_name = "Sed";
#define MODSED_OUTBUF_SIZE 8000
#define MAX_TRANSIENT_BUCKETS 50

typedef struct sed_expr_config
{
    sed_commands_t *sed_cmds;
    const char *last_error;
} sed_expr_config;

typedef struct sed_config
{
    sed_expr_config output;
    sed_expr_config input;
} sed_config;

/* Context for filter invocation for single HTTP request */
typedef struct sed_filter_ctxt
{
    sed_eval_t eval;
    ap_filter_t *f;
    request_rec *r;
    apr_bucket_brigade *bb;
    apr_bucket_brigade *bbinp;
    char *outbuf;
    char *curoutbuf;
    int bufsize;
    apr_pool_t *tpool;
    int numbuckets;
} sed_filter_ctxt;

module AP_MODULE_DECLARE_DATA sed_module;

/* This function will be call back from libsed functions if there is any error
 * happend during execution of sed scripts
 */
static apr_status_t log_sed_errf(void *data, const char *error)
{
    request_rec *r = (request_rec *) data;
    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02998) "%s", error);
    return APR_SUCCESS;
}

/* This function will be call back from libsed functions if there is any
 * compilation error.
 */
static apr_status_t sed_compile_errf(void *data, const char *error)
{
    sed_expr_config *sed_cfg = (sed_expr_config *) data;
    sed_cfg->last_error = error;
    return APR_SUCCESS;
}

/* clear the temporary pool (used for transient buckets)
 */
static void clear_ctxpool(sed_filter_ctxt* ctx)
{
    apr_pool_clear(ctx->tpool);
    ctx->outbuf = NULL;
    ctx->curoutbuf = NULL;
    ctx->numbuckets = 0;
}

/* alloc_outbuf
 * allocate output buffer
 */
static void alloc_outbuf(sed_filter_ctxt* ctx)
{
    ctx->outbuf = apr_palloc(ctx->tpool, ctx->bufsize + 1);
    ctx->curoutbuf = ctx->outbuf;
}

/* append_bucket
 * Allocate a new bucket from buf and sz and append to ctx->bb
 */
static apr_status_t append_bucket(sed_filter_ctxt* ctx, char* buf, int sz)
{
    apr_status_t status = APR_SUCCESS;
    apr_bucket *b;
    if (ctx->tpool == ctx->r->pool) {
        /* We are not using transient bucket */
        b = apr_bucket_pool_create(buf, sz, ctx->r->pool,
                                   ctx->r->connection->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
    }
    else {
        /* We are using transient bucket */
        b = apr_bucket_transient_create(buf, sz,
                                        ctx->r->connection->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
        ctx->numbuckets++;
        if (ctx->numbuckets >= MAX_TRANSIENT_BUCKETS) {
            b = apr_bucket_flush_create(ctx->r->connection->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
            status = ap_pass_brigade(ctx->f->next, ctx->bb);
            apr_brigade_cleanup(ctx->bb);
            clear_ctxpool(ctx);
        }
    }
    return status;
}

/*
 * flush_output_buffer
 * Flush the  output data (stored in ctx->outbuf)
 */
static apr_status_t flush_output_buffer(sed_filter_ctxt *ctx)
{
    int size = ctx->curoutbuf - ctx->outbuf;
    char *out;
    apr_status_t status = APR_SUCCESS;
    if ((ctx->outbuf == NULL) || (size <=0))
        return status;
    out = apr_pmemdup(ctx->tpool, ctx->outbuf, size);
    status = append_bucket(ctx, out, size);
    ctx->curoutbuf = ctx->outbuf;
    return status;
}

/* This is a call back function. When libsed wants to generate the output,
 * this function will be invoked.
 */
static apr_status_t sed_write_output(void *dummy, char *buf, int sz)
{
    /* dummy is basically filter context. Context is passed during invocation
     * of sed_eval_buffer
     */
    int remainbytes = 0;
    apr_status_t status = APR_SUCCESS;
    sed_filter_ctxt *ctx = (sed_filter_ctxt *) dummy;
    if (ctx->outbuf == NULL) {
        alloc_outbuf(ctx);
    }
    remainbytes = ctx->bufsize - (ctx->curoutbuf - ctx->outbuf);
    if (sz >= remainbytes) {
        if (remainbytes > 0) {
            memcpy(ctx->curoutbuf, buf, remainbytes);
            buf += remainbytes;
            sz -= remainbytes;
            ctx->curoutbuf += remainbytes;
        }
        /* buffer is now full */
        status = append_bucket(ctx, ctx->outbuf, ctx->bufsize);
        /* old buffer is now used so allocate new buffer */
        alloc_outbuf(ctx);
        /* if size is bigger than the allocated buffer directly add to output
         * brigade */
        if ((status == APR_SUCCESS) && (sz >= ctx->bufsize)) {
            char* newbuf = apr_pmemdup(ctx->tpool, buf, sz);
            status = append_bucket(ctx, newbuf, sz);
            /* pool might get clear after append_bucket */
            if (ctx->outbuf == NULL) {
                alloc_outbuf(ctx);
            }
        }
        else {
            memcpy(ctx->curoutbuf, buf, sz);
            ctx->curoutbuf += sz;
        }
    }
    else {
        memcpy(ctx->curoutbuf, buf, sz);
        ctx->curoutbuf += sz;
    }
    return status;
}

/* Compile a sed expression. Compiled context is saved in sed_cfg->sed_cmds.
 * Memory required for compilation context is allocated from cmd->pool.
 */
static apr_status_t compile_sed_expr(sed_expr_config *sed_cfg,
                                     cmd_parms *cmd,
                                     const char *expr)
{
    apr_status_t status = APR_SUCCESS;

    if (!sed_cfg->sed_cmds) {
        sed_commands_t *sed_cmds;
        sed_cmds = apr_pcalloc(cmd->pool, sizeof(sed_commands_t));
        status = sed_init_commands(sed_cmds, sed_compile_errf, sed_cfg,
                                   cmd->pool);
        if (status != APR_SUCCESS) {
            sed_destroy_commands(sed_cmds);
            return status;
        }
        sed_cfg->sed_cmds = sed_cmds;
    }
    status = sed_compile_string(sed_cfg->sed_cmds, expr);
    if (status != APR_SUCCESS) {
        sed_destroy_commands(sed_cfg->sed_cmds);
        sed_cfg->sed_cmds = NULL;
    }
    return status;
}

/* sed eval cleanup function */
static apr_status_t sed_eval_cleanup(void *data)
{
    sed_eval_t *eval = (sed_eval_t *) data;
    sed_destroy_eval(eval);
    return APR_SUCCESS;
}

/* Initialize sed filter context. If successful then context is set in f->ctx
 */
static apr_status_t init_context(ap_filter_t *f, sed_expr_config *sed_cfg, int usetpool)
{
    apr_status_t status;
    sed_filter_ctxt* ctx;
    request_rec *r = f->r;
    /* Create the context. Call sed_init_eval. libsed will generated
     * output by calling sed_write_output and generates any error by
     * invoking log_sed_errf.
     */
    ctx = apr_pcalloc(r->pool, sizeof(sed_filter_ctxt));
    ctx->r = r;
    ctx->bb = NULL;
    ctx->numbuckets = 0;
    ctx->f = f;
    status = sed_init_eval(&ctx->eval, sed_cfg->sed_cmds, log_sed_errf,
                           r, &sed_write_output, r->pool);
    if (status != APR_SUCCESS) {
        return status;
    }
    apr_pool_cleanup_register(r->pool, &ctx->eval, sed_eval_cleanup,
                              apr_pool_cleanup_null);
    ctx->bufsize = MODSED_OUTBUF_SIZE;
    if (usetpool) {
        apr_pool_create(&(ctx->tpool), r->pool);
    }
    else {
        ctx->tpool = r->pool;
    }
    alloc_outbuf(ctx);
    f->ctx = ctx;
    return APR_SUCCESS;
}

/* Entry function for Sed output filter */
static apr_status_t sed_response_filter(ap_filter_t *f,
                                        apr_bucket_brigade *bb)
{
    apr_bucket *b;
    apr_status_t status = APR_SUCCESS;
    sed_config *cfg = ap_get_module_config(f->r->per_dir_config,
                                           &sed_module);
    sed_filter_ctxt *ctx = f->ctx;
    sed_expr_config *sed_cfg = &cfg->output;

    if ((sed_cfg == NULL) || (sed_cfg->sed_cmds == NULL)) {
        /* No sed expressions */
        ap_remove_output_filter(f);
        return ap_pass_brigade(f->next, bb);
    }

    if (ctx == NULL) {

        if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bb))) {
            /* no need to run sed filter for Head requests */
            ap_remove_output_filter(f);
            return ap_pass_brigade(f->next, bb);
        }

        status = init_context(f, sed_cfg, 1);
        if (status != APR_SUCCESS)
             return status;
        ctx = f->ctx;
        apr_table_unset(f->r->headers_out, "Content-Length");

        ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
    }

    /* Here is the main logic. Iterate through all the buckets, read the
     * content of the bucket, call sed_eval_buffer on the data.
     * sed_eval_buffer will read the data line by line, run filters on each
     * line. sed_eval_buffer will generates the output by calling
     * sed_write_output which will add the output to ctx->bb. At the end of
     * the loop, ctx->bb is passed to the next filter in chain. At the end of
     * the data, if new line is not found then sed_eval_buffer will store the
     * data in its own buffer.
     *
     * Once eos bucket is found then sed_finalize_eval will flush the rest of
     * the data. If there is no new line in last line of data, new line is
     * appended (that is a solaris sed behavior). libsed's internal memory for
     * evaluation is allocated on request's pool so it will be cleared once
     * request is over.
     *
     * If flush bucket is found then append the flush bucket to ctx->bb
     * and pass it to next filter. There may be some data which will still be
     * in sed's internal buffer which can't be flushed until new line
     * character is arrived.
     */
    while (!APR_BRIGADE_EMPTY(bb)) {
        b = APR_BRIGADE_FIRST(bb);
        if (APR_BUCKET_IS_EOS(b)) {
            /* Now clean up the internal sed buffer */
            sed_finalize_eval(&ctx->eval, ctx);
            status = flush_output_buffer(ctx);
            if (status != APR_SUCCESS) {
                break;
            }
            /* Move the eos bucket to ctx->bb brigade */
            APR_BUCKET_REMOVE(b);
            APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
        }
        else if (APR_BUCKET_IS_FLUSH(b)) {
            status = flush_output_buffer(ctx);
            if (status != APR_SUCCESS) {
                break;
            }
            /* Move the flush bucket to ctx->bb brigade */
            APR_BUCKET_REMOVE(b);
            APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
        }
        else {
            if (!APR_BUCKET_IS_METADATA(b)) {
                const char *buf = NULL;
                apr_size_t bytes = 0;

                status = apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ);
                if (status == APR_SUCCESS) {
                    status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx);
                }
                if (status != APR_SUCCESS) {
                    break;
                }
            }
            apr_bucket_delete(b);
        }
    }
    if (status == APR_SUCCESS) {
        status = flush_output_buffer(ctx);
    }
    if (!APR_BRIGADE_EMPTY(ctx->bb)) {
        if (status == APR_SUCCESS) {
            status = ap_pass_brigade(f->next, ctx->bb);
        }
        apr_brigade_cleanup(ctx->bb);
    }
    clear_ctxpool(ctx);
    return status;
}

/* Entry function for Sed input filter */
static apr_status_t sed_request_filter(ap_filter_t *f,
                                       apr_bucket_brigade *bb,
                                       ap_input_mode_t mode,
                                       apr_read_type_e block,
                                       apr_off_t readbytes)
{
    sed_config *cfg = ap_get_module_config(f->r->per_dir_config,
                                           &sed_module);
    sed_filter_ctxt *ctx = f->ctx;
    apr_status_t status;
    apr_bucket_brigade *bbinp;
    sed_expr_config *sed_cfg = &cfg->input;

    if (mode != AP_MODE_READBYTES) {
        return ap_get_brigade(f->next, bb, mode, block, readbytes);
    }

    if ((sed_cfg == NULL) || (sed_cfg->sed_cmds == NULL)) {
        /* No sed expression */
        return ap_get_brigade(f->next, bb, mode, block, readbytes);
    }

    if (!ctx) {
        if (!ap_is_initial_req(f->r)) {
            ap_remove_input_filter(f);
            /* XXX : Should we filter the sub requests too */
            return ap_get_brigade(f->next, bb, mode, block, readbytes);
        }
        status = init_context(f, sed_cfg, 0);
        if (status != APR_SUCCESS)
             return status;
        ctx = f->ctx;
        ctx->bb    = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
        ctx->bbinp = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
    }

    bbinp = ctx->bbinp;

    /* Here is the logic :
     * Read the readbytes data from next level fiter into bbinp. Loop through
     * the buckets in bbinp and read the data from buckets and invoke
     * sed_eval_buffer on the data. libsed will generate its output using
     * sed_write_output which will add data in ctx->bb. Do it until it have
     * atleast one bucket in ctx->bb. At the end of data eos bucket
     * should be there.
     *
     * Once eos bucket is seen, then invoke sed_finalize_eval to clear the
     * output. If the last byte of data is not a new line character then sed
     * will add a new line to the data that is default sed behaviour. Note
     * that using this filter with POST data, caller may not expect this
     * behaviour.
     *
     * If next level fiter generate the flush bucket, we can't do much about
     * it. If we want to return the flush bucket in brigade bb (to the caller)
     * the question is where to add it?
     */
    while (APR_BRIGADE_EMPTY(ctx->bb)) {
        apr_bucket *b;

        /* read the bytes from next level filter */
        apr_brigade_cleanup(bbinp);
        status = ap_get_brigade(f->next, bbinp, mode, block, readbytes);
        if (status != APR_SUCCESS) {
            return status;
        }
        for (b = APR_BRIGADE_FIRST(bbinp); b != APR_BRIGADE_SENTINEL(bbinp);
             b = APR_BUCKET_NEXT(b)) {
            const char *buf = NULL;
            apr_size_t bytes;

            if (APR_BUCKET_IS_EOS(b)) {
                /* eos bucket. Clear the internal sed buffers */
                sed_finalize_eval(&ctx->eval, ctx);
                flush_output_buffer(ctx);
                APR_BUCKET_REMOVE(b);
                APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
                break;
            }
            else if (APR_BUCKET_IS_FLUSH(b)) {
                /* What should we do with flush bucket */
                continue;
            }
            if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ)
                     == APR_SUCCESS) {
                status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx);
                if (status != APR_SUCCESS)
                    return status;
                flush_output_buffer(ctx);
            }
        }
    }

    if (!APR_BRIGADE_EMPTY(ctx->bb)) {
        apr_bucket *b = NULL;

        if (apr_brigade_partition(ctx->bb, readbytes, &b) == APR_INCOMPLETE) {
            APR_BRIGADE_CONCAT(bb, ctx->bb);
        }
        else {
            APR_BRIGADE_CONCAT(bb, ctx->bb);
            apr_brigade_split_ex(bb, b, ctx->bb);
        }
    }
    return APR_SUCCESS;
}

static const char *sed_add_expr(cmd_parms *cmd, void *cfg, const char *arg)
{
    int offset = (int) (long) cmd->info;
    sed_expr_config *sed_cfg =
                (sed_expr_config *) (((char *) cfg) + offset);
    if (compile_sed_expr(sed_cfg, cmd, arg) != APR_SUCCESS) {
        return apr_psprintf(cmd->temp_pool,
                            "Failed to compile sed expression. %s",
                            sed_cfg->last_error);
    }
    return NULL;
}

static void *create_sed_dir_config(apr_pool_t *p, char *s)
{
    sed_config *cfg = apr_pcalloc(p, sizeof(sed_config));
    return cfg;
}

static const command_rec sed_filter_cmds[] = {
    AP_INIT_TAKE1("OutputSed", sed_add_expr,
                  (void *) APR_OFFSETOF(sed_config, output),
                  ACCESS_CONF,
                  "Sed regular expression for Response"),
    AP_INIT_TAKE1("InputSed", sed_add_expr,
                  (void *) APR_OFFSETOF(sed_config, input),
                  ACCESS_CONF,
                  "Sed regular expression for Request"),
    {NULL}
};

static void register_hooks(apr_pool_t *p)
{
    ap_register_output_filter(sed_filter_name, sed_response_filter, NULL,
                              AP_FTYPE_RESOURCE);
    ap_register_input_filter(sed_filter_name, sed_request_filter, NULL,
                             AP_FTYPE_RESOURCE);
}

AP_DECLARE_MODULE(sed) = {
    STANDARD20_MODULE_STUFF,
    create_sed_dir_config,      /* dir config creater */
    NULL,                       /* dir merger --- default is to override */
    NULL,                       /* server config */
    NULL,                       /* merge server config */
    sed_filter_cmds,            /* command table */
    register_hooks              /* register hooks */
};
