/* 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 "httpd.h"
#include "http_core.h"

#include "util_filter.h"
#include "http_log.h"
#include "http_config.h"
#include "http_request.h"
#include "http_protocol.h"



#include "ap_mpm.h"

module AP_MODULE_DECLARE_DATA dialup_module;

typedef struct dialup_dcfg_t {
    apr_size_t bytes_per_second;
} dialup_dcfg_t;

typedef struct dialup_baton_t {
    apr_size_t bytes_per_second;
    request_rec *r;
    apr_file_t *fd;
    apr_bucket_brigade *bb;
    apr_bucket_brigade *tmpbb;
} dialup_baton_t;

static int
dialup_send_pulse(dialup_baton_t *db)
{
    int status;
    apr_off_t len = 0;
    apr_size_t bytes_sent = 0;

    while (!APR_BRIGADE_EMPTY(db->bb) && bytes_sent < db->bytes_per_second) {
        apr_bucket *e;

        if (db->r->connection->aborted) {
            return HTTP_INTERNAL_SERVER_ERROR;
        }

        status = apr_brigade_partition(db->bb, db->bytes_per_second, &e);

        if (status != APR_SUCCESS && status != APR_INCOMPLETE) {
            /* XXXXXX: Log me. */
            return HTTP_INTERNAL_SERVER_ERROR;
        }

        if (e != APR_BRIGADE_SENTINEL(db->bb)) {
            apr_bucket *f;
            apr_bucket *b = APR_BUCKET_PREV(e);
            f = APR_RING_FIRST(&db->bb->list);
            APR_RING_UNSPLICE(f, b, link);
            APR_RING_SPLICE_HEAD(&db->tmpbb->list, f, b, apr_bucket, link);
        }
        else {
            APR_BRIGADE_CONCAT(db->tmpbb, db->bb);
        }

        e = apr_bucket_flush_create(db->r->connection->bucket_alloc);

        APR_BRIGADE_INSERT_TAIL(db->tmpbb, e);

        apr_brigade_length(db->tmpbb, 1, &len);
        bytes_sent += len;
        status = ap_pass_brigade(db->r->output_filters, db->tmpbb);

        apr_brigade_cleanup(db->tmpbb);

        if (status != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, db->r, APLOGNO(01867)
                          "dialup: pulse: ap_pass_brigade failed:");
            return AP_FILTER_ERROR;
        }
    }

    if (APR_BRIGADE_EMPTY(db->bb)) {
        return DONE;
    }
    else {
        return SUSPENDED;
    }
}

static void
dialup_callback(void *baton)
{
    int status;
    dialup_baton_t *db = (dialup_baton_t *)baton;
    conn_rec *c = db->r->connection;

    apr_thread_mutex_lock(db->r->invoke_mtx);

    status = dialup_send_pulse(db);

    if (status == SUSPENDED) {
        ap_mpm_register_timed_callback(apr_time_from_sec(1), dialup_callback, baton);
    }
    else if (status == DONE) {
        apr_thread_mutex_unlock(db->r->invoke_mtx);
        ap_finalize_request_protocol(db->r);
        ap_process_request_after_handler(db->r);
        return;
    }
    else {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, db->r, APLOGNO(01868)
                      "dialup: pulse returned: %d", status);
        db->r->status = HTTP_OK;
        ap_die(status, db->r);
    }

    apr_thread_mutex_unlock(db->r->invoke_mtx);

    ap_mpm_resume_suspended(c);
}

static int
dialup_handler(request_rec *r)
{
    int status;
    apr_status_t rv;
    dialup_dcfg_t *dcfg;
    core_dir_config *ccfg;
    apr_file_t *fd;
    dialup_baton_t *db;
    apr_bucket *e;
    int mpm_can_suspend = 0;

    /* See core.c, default handler for all of the cases we just decline. */
    if (r->method_number != M_GET ||
        r->finfo.filetype == APR_NOFILE ||
        r->finfo.filetype == APR_DIR) {
        return DECLINED;
    }

    rv = ap_mpm_query(AP_MPMQ_CAN_SUSPEND, &mpm_can_suspend);
    if (!mpm_can_suspend) {
        ap_log_rerror (APLOG_MARK, APLOG_NOTICE, rv, r, APLOGNO(02637)
                "dialup: MPM doesn't support suspending");
        return DECLINED;
    }

    dcfg = ap_get_module_config(r->per_dir_config,
                                &dialup_module);

    if (dcfg->bytes_per_second == 0) {
        return DECLINED;
    }

    ccfg = ap_get_core_module_config(r->per_dir_config);


    rv = apr_file_open(&fd, r->filename, APR_READ | APR_BINARY
#if APR_HAS_SENDFILE
                           | AP_SENDFILE_ENABLED(ccfg->enable_sendfile)
#endif
                       , 0, r->pool);

    if (rv) {
        return DECLINED;
    }

    /* copied from default handler: */
    ap_update_mtime(r, r->finfo.mtime);
    ap_set_last_modified(r);
    ap_set_etag(r);
    ap_set_accept_ranges(r);
    ap_set_content_length(r, r->finfo.size);

    status = ap_meets_conditions(r);
    if (status != OK) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01869)
                      "dialup: declined, meets conditions, good luck core handler");
        return DECLINED;
    }

    db = apr_palloc(r->pool, sizeof(dialup_baton_t));

    db->bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    db->tmpbb = apr_brigade_create(r->pool, r->connection->bucket_alloc);

    e = apr_brigade_insert_file(db->bb, fd, 0, r->finfo.size, r->pool);

#if APR_HAS_MMAP
    if (ccfg->enable_mmap == ENABLE_MMAP_OFF) {
        apr_bucket_file_enable_mmap(e, 0);
    }
#endif


    db->bytes_per_second = dcfg->bytes_per_second;
    db->r = r;
    db->fd = fd;

    e = apr_bucket_eos_create(r->connection->bucket_alloc);

    APR_BRIGADE_INSERT_TAIL(db->bb, e);

    status = dialup_send_pulse(db);
    if (status != SUSPENDED && status != DONE) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01870)
                      "dialup: failed, send pulse");
        return status;
    }

    ap_mpm_register_timed_callback(apr_time_from_sec(1), dialup_callback, db);

    return SUSPENDED;
}



#ifndef APR_HOOK_ALMOST_LAST
#define APR_HOOK_ALMOST_LAST (APR_HOOK_REALLY_LAST - 1)
#endif

static void
dialup_register_hooks(apr_pool_t *p)
{
    ap_hook_handler(dialup_handler, NULL, NULL, APR_HOOK_ALMOST_LAST);
}

typedef struct modem_speed_t {
    const char *name;
    apr_size_t bytes_per_second;
} modem_speed_t;

#ifndef BITRATE_TO_BYTES
#define BITRATE_TO_BYTES(x) ((1000 * x)/8)
#endif

static const modem_speed_t modem_bitrates[] =
{
    {"V.21",    BITRATE_TO_BYTES(0.1)},
    {"V.26bis", BITRATE_TO_BYTES(2.4)},
    {"V.32",    BITRATE_TO_BYTES(9.6)},
    {"V.34",    BITRATE_TO_BYTES(28.8)},
    {"V.92",    BITRATE_TO_BYTES(56.0)},
    {"i-was-rich-and-got-a-leased-line", BITRATE_TO_BYTES(1500)},
    {NULL, 0}
};

static const char *
cmd_modem_standard(cmd_parms *cmd,
             void *dconf,
             const char *input)
{
    const modem_speed_t *standard;
    int i = 0;
    dialup_dcfg_t *dcfg = (dialup_dcfg_t*)dconf;

    dcfg->bytes_per_second = 0;

    while (modem_bitrates[i].name != NULL) {
        standard = &modem_bitrates[i];
        if (strcasecmp(standard->name, input) == 0) {
            dcfg->bytes_per_second = standard->bytes_per_second;
            break;
        }
        i++;
    }

    if (dcfg->bytes_per_second == 0) {
        return "mod_diaulup: Unkonwn Modem Standard specified.";
    }

    return NULL;
}

static void *
dialup_dcfg_create(apr_pool_t *p, char *dummy)
{
    dialup_dcfg_t *cfg = apr_palloc(p, sizeof(dialup_dcfg_t));

    cfg->bytes_per_second = 0;

    return cfg;
}


static const command_rec dialup_cmds[] =
{
    AP_INIT_TAKE1("ModemStandard", cmd_modem_standard, NULL, ACCESS_CONF,
                  "Modem Standard to.. simulate. "
                  "Must be one of: 'V.21', 'V.26bis', 'V.32', 'V.34', or 'V.92'"),
    {NULL}
};

AP_DECLARE_MODULE(dialup) =
{
    STANDARD20_MODULE_STUFF,
    dialup_dcfg_create,
    NULL,
    NULL,
    NULL,
    dialup_cmds,
    dialup_register_hooks
};
