/* 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 "mod_session.h"
#include "apr_lib.h"
#include "apr_strings.h"
#include "http_log.h"
#include "util_cookies.h"
#include "apr_dbd.h"
#include "mod_dbd.h"
#include "mpm_common.h"

#define MOD_SESSION_DBD "mod_session_dbd"

module AP_MODULE_DECLARE_DATA session_dbd_module;

/**
 * Structure to carry the per-dir session config.
 */
typedef struct {
    const char *name;
    int name_set;
    const char *name_attrs;
    const char *name2;
    int name2_set;
    const char *name2_attrs;
    int peruser;
    int peruser_set;
    int remove;
    int remove_set;
    const char *selectlabel;
    const char *insertlabel;
    const char *updatelabel;
    const char *deletelabel;
} session_dbd_dir_conf;

/* optional function - look it up once in post_config */
static ap_dbd_t *(*session_dbd_acquire_fn) (request_rec *) = NULL;
static void (*session_dbd_prepare_fn) (server_rec *, const char *, const char *) = NULL;

/**
 * Initialise the database.
 *
 * If the mod_dbd module is missing, this method will return APR_EGENERAL.
 */
static apr_status_t dbd_init(request_rec *r, const char *query, ap_dbd_t **dbdp,
                             apr_dbd_prepared_t **statementp)
{
    ap_dbd_t *dbd;
    apr_dbd_prepared_t *statement;

    if (!session_dbd_prepare_fn || !session_dbd_acquire_fn) {
        session_dbd_prepare_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_prepare);
        session_dbd_acquire_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire);
        if (!session_dbd_prepare_fn || !session_dbd_acquire_fn) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01850)
                          "You must load mod_dbd to enable AuthDBD functions");
            return APR_EGENERAL;
        }
    }

    dbd = session_dbd_acquire_fn(r);
    if (!dbd) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01851)
                      "failed to acquire database connection");
        return APR_EGENERAL;
    }

    statement = apr_hash_get(dbd->prepared, query, APR_HASH_KEY_STRING);
    if (!statement) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01852)
                      "failed to find the prepared statement called '%s'", query);
        return APR_EGENERAL;
    }

    *dbdp = dbd;
    *statementp = statement;

    return APR_SUCCESS;
}

/**
 * Load the session by the key specified.
 *
 * The session value is allocated using the passed apr_pool_t.
 */
static apr_status_t dbd_load(apr_pool_t *p, request_rec * r,
                             const char *key, const char **val)
{

    apr_status_t rv;
    ap_dbd_t *dbd = NULL;
    apr_dbd_prepared_t *statement = NULL;
    apr_dbd_results_t *res = NULL;
    apr_dbd_row_t *row = NULL;
    apr_int64_t expiry = (apr_int64_t) apr_time_now();

    session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                      &session_dbd_module);

    if (conf->selectlabel == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01853)
                      "no SessionDBDselectlabel has been specified");
        return APR_EGENERAL;
    }

    rv = dbd_init(r, conf->selectlabel, &dbd, &statement);
    if (rv) {
        return rv;
    }
    rv = apr_dbd_pvbselect(dbd->driver, r->pool, dbd->handle, &res, statement,
                          0, key, &expiry, NULL);
    if (rv) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01854)
                      "query execution error saving session '%s' "
                      "in database using query '%s': %s", key, conf->selectlabel,
                      apr_dbd_error(dbd->driver, dbd->handle, rv));
        return APR_EGENERAL;
    }
    for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
         rv != -1;
         rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
        if (rv != 0) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01855)
                          "error retrieving results while saving '%s' "
                          "in database using query '%s': %s", key, conf->selectlabel,
                           apr_dbd_error(dbd->driver, dbd->handle, rv));
            return APR_EGENERAL;
        }
        if (*val == NULL) {
            *val = apr_pstrdup(p, apr_dbd_get_entry(dbd->driver, row, 0));
        }
        /* we can't break out here or row won't get cleaned up */
    }

    return APR_SUCCESS;

}

/**
 * Load the session by firing off a dbd query.
 *
 * If the session is anonymous, the session key will be extracted from
 * the cookie specified. Failing that, the session key will be extracted
 * from the GET parameters.
 *
 * If the session is keyed by the username, the session will be extracted
 * by that.
 *
 * If no session is found, an empty session will be created.
 *
 * On success, this returns OK.
 */
static apr_status_t session_dbd_load(request_rec * r, session_rec ** z)
{

    session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                      &session_dbd_module);

    apr_status_t ret = APR_SUCCESS;
    session_rec *zz = NULL;
    const char *name = NULL;
    const char *note = NULL;
    const char *val = NULL;
    const char *key = NULL;
    request_rec *m = r->main ? r->main : r;

    /* is our session in a cookie? */
    if (conf->name2_set) {
        name = conf->name2;
    }
    else if (conf->name_set) {
        name = conf->name;
    }
    else if (conf->peruser_set && r->user) {
        name = r->user;
    }
    else {
        return DECLINED;
    }

    /* first look in the notes */
    note = apr_pstrcat(m->pool, MOD_SESSION_DBD, name, NULL);
    zz = (session_rec *)apr_table_get(m->notes, note);
    if (zz) {
        *z = zz;
        return OK;
    }

    /* load anonymous sessions */
    if (conf->name_set || conf->name2_set) {

        /* load an RFC2109 or RFC2965 compliant cookie */
        ap_cookie_read(r, name, &key, conf->remove);
        if (key) {
            ret = dbd_load(m->pool, r, key, &val);
            if (ret != APR_SUCCESS) {
                return ret;
            }
        }

    }

    /* load named session */
    else if (conf->peruser) {
        if (r->user) {
            ret = dbd_load(m->pool, r, r->user, &val);
            if (ret != APR_SUCCESS) {
                return ret;
            }
        }
    }

    /* otherwise not for us */
    else {
        return DECLINED;
    }

    /* create a new session and return it */
    zz = (session_rec *) apr_pcalloc(m->pool, sizeof(session_rec));
    zz->pool = m->pool;
    zz->entries = apr_table_make(zz->pool, 10);
    if (key && val) {
        apr_uuid_t *uuid = apr_pcalloc(zz->pool, sizeof(apr_uuid_t));
        if (APR_SUCCESS == apr_uuid_parse(uuid, key)) {
            zz->uuid = uuid;
        }
    }
    zz->encoded = val;
    *z = zz;

    /* put the session in the notes so we don't have to parse it again */
    apr_table_setn(m->notes, note, (char *)zz);

    /* don't cache pages with a session */
    apr_table_addn(r->headers_out, "Cache-Control", "no-cache, private");

    return OK;

}

/**
 * Save the session by the key specified.
 */
static apr_status_t dbd_save(request_rec * r, const char *oldkey,
        const char *newkey, const char *val, apr_int64_t expiry)
{

    apr_status_t rv;
    ap_dbd_t *dbd = NULL;
    apr_dbd_prepared_t *statement;
    int rows = 0;

    session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                      &session_dbd_module);

    if (conf->updatelabel == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01856)
                      "no SessionDBDupdatelabel has been specified");
        return APR_EGENERAL;
    }

    rv = dbd_init(r, conf->updatelabel, &dbd, &statement);
    if (rv) {
        return rv;
    }

    if (oldkey) {
        rv = apr_dbd_pvbquery(dbd->driver, r->pool, dbd->handle, &rows,
                statement, val, &expiry, newkey, oldkey, NULL);
        if (rv) {
            ap_log_rerror(
                    APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01857) "query execution error updating session '%s' "
                    "using database query '%s': %s/%s", oldkey, newkey, conf->updatelabel, apr_dbd_error(dbd->driver, dbd->handle, rv));
            return APR_EGENERAL;
        }

        /*
         * if some rows were updated it means a session existed and was updated,
         * so we are done.
         */
        if (rows != 0) {
            return APR_SUCCESS;
        }
    }

    if (conf->insertlabel == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01858)
                      "no SessionDBDinsertlabel has been specified");
        return APR_EGENERAL;
    }

    rv = dbd_init(r, conf->insertlabel, &dbd, &statement);
    if (rv) {
        return rv;
    }
    rv = apr_dbd_pvbquery(dbd->driver, r->pool, dbd->handle, &rows, statement,
                          val, &expiry, newkey, NULL);
    if (rv) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01859)
                      "query execution error inserting session '%s' "
                      "in database with '%s': %s", newkey, conf->insertlabel,
                      apr_dbd_error(dbd->driver, dbd->handle, rv));
        return APR_EGENERAL;
    }

    /*
     * if some rows were inserted it means a session was inserted, so we are
     * done.
     */
    if (rows != 0) {
        return APR_SUCCESS;
    }

    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01860)
                  "the session insert query did not cause any rows to be added "
                  "to the database for session '%s', session not inserted", newkey);

    return APR_EGENERAL;

}

/**
 * Remove the session by the key specified.
 */
static apr_status_t dbd_remove(request_rec * r, const char *key)
{

    apr_status_t rv;
    ap_dbd_t *dbd;
    apr_dbd_prepared_t *statement;
    int rows = 0;

    session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                      &session_dbd_module);

    if (conf->deletelabel == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01862)
                      "no SessionDBDdeletelabel has been specified");
        return APR_EGENERAL;
    }

    rv = dbd_init(r, conf->deletelabel, &dbd, &statement);
    if (rv != APR_SUCCESS) {
        /* No need to do additional error logging here, it has already
           been done in dbd_init if needed */
        return rv;
    }

    rv = apr_dbd_pvbquery(dbd->driver, r->pool, dbd->handle, &rows, statement,
                          key, NULL);
    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01864)
                      "query execution error removing session '%s' "
                      "from database", key);
        return rv;
    }

    return APR_SUCCESS;

}

/**
 * Clean out expired sessions.
 *
 * TODO: We need to figure out a way to clean out expired sessions from the database.
 * The monitor hook doesn't help us that much, as we have no handle into the
 * server, and so we need to come up with a way to do this safely.
 */
static apr_status_t dbd_clean(apr_pool_t *p, server_rec *s)
{

    return APR_ENOTIMPL;

}

/**
 * Save the session by firing off a dbd query.
 *
 * If the session is anonymous, save the session and write a cookie
 * containing the uuid.
 *
 * If the session is keyed to the username, save the session using
 * the username as a key.
 *
 * On success, this method will return APR_SUCCESS.
 *
 * @param r The request pointer.
 * @param z A pointer to where the session will be written.
 */
static apr_status_t session_dbd_save(request_rec * r, session_rec * z)
{

    apr_status_t ret = APR_SUCCESS;
    session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                      &session_dbd_module);

    /* support anonymous sessions */
    if (conf->name_set || conf->name2_set) {
        char *oldkey = NULL, *newkey = NULL;

        /* if the session is new or changed, make a new session ID */
        if (z->uuid) {
            oldkey = apr_pcalloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
            apr_uuid_format(oldkey, z->uuid);
        }
        if (z->dirty || !oldkey) {
            z->uuid = apr_pcalloc(z->pool, sizeof(apr_uuid_t));
            apr_uuid_get(z->uuid);
            newkey = apr_pcalloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
            apr_uuid_format(newkey, z->uuid);
        }
        else {
            newkey = oldkey;
        }

        /* save the session with the uuid as key */
        if (z->encoded && z->encoded[0]) {
            ret = dbd_save(r, oldkey, newkey, z->encoded, z->expiry);
        }
        else {
            ret = dbd_remove(r, oldkey);
        }
        if (ret != APR_SUCCESS) {
            return ret;
        }

        /* create RFC2109 compliant cookie */
        if (conf->name_set) {
            ap_cookie_write(r, conf->name, newkey, conf->name_attrs, z->maxage,
                            r->headers_out, r->err_headers_out, NULL);
        }

        /* create RFC2965 compliant cookie */
        if (conf->name2_set) {
            ap_cookie_write2(r, conf->name2, newkey, conf->name2_attrs, z->maxage,
                             r->headers_out, r->err_headers_out, NULL);
        }

        return OK;

    }

    /* save named session */
    else if (conf->peruser) {

        /* don't cache pages with a session */
        apr_table_addn(r->headers_out, "Cache-Control", "no-cache, private");

        if (r->user) {
            ret = dbd_save(r, r->user, r->user, z->encoded, z->expiry);
            if (ret != APR_SUCCESS) {
                return ret;
            }
            return OK;
        }
        else {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01865)
               "peruser sessions can only be saved if a user is logged in, "
                          "session not saved: %s", r->uri);
        }
    }

    return DECLINED;

}

/**
 * This function performs housekeeping on the database, deleting expired
 * sessions.
 */
static int session_dbd_monitor(apr_pool_t *p, server_rec *s)
{
    /* TODO handle housekeeping */
    dbd_clean(p, s);
    return OK;
}


static void *create_session_dbd_dir_config(apr_pool_t * p, char *dummy)
{
    session_dbd_dir_conf *new =
    (session_dbd_dir_conf *) apr_pcalloc(p, sizeof(session_dbd_dir_conf));

    new->remove = 1;

    new->selectlabel = "selectsession";
    new->insertlabel = "insertsession";
    new->updatelabel = "updatesession";
    new->deletelabel = "deletesession";

    return (void *) new;
}

static void *merge_session_dbd_dir_config(apr_pool_t * p, void *basev, void *addv)
{
    session_dbd_dir_conf *new = (session_dbd_dir_conf *) apr_pcalloc(p, sizeof(session_dbd_dir_conf));
    session_dbd_dir_conf *add = (session_dbd_dir_conf *) addv;
    session_dbd_dir_conf *base = (session_dbd_dir_conf *) basev;

    new->name = (add->name_set == 0) ? base->name : add->name;
    new->name_attrs = (add->name_set == 0) ? base->name_attrs : add->name_attrs;
    new->name_set = add->name_set || base->name_set;
    new->name2 = (add->name2_set == 0) ? base->name2 : add->name2;
    new->name2_attrs = (add->name2_set == 0) ? base->name2_attrs : add->name2_attrs;
    new->name2_set = add->name2_set || base->name2_set;
    new->peruser = (add->peruser_set == 0) ? base->peruser : add->peruser;
    new->peruser_set = add->peruser_set || base->peruser_set;
    new->remove = (add->remove_set == 0) ? base->remove : add->remove;
    new->remove_set = add->remove_set || base->remove_set;
    new->selectlabel = (!add->selectlabel) ? base->selectlabel : add->selectlabel;
    new->updatelabel = (!add->updatelabel) ? base->updatelabel : add->updatelabel;
    new->insertlabel = (!add->insertlabel) ? base->insertlabel : add->insertlabel;
    new->deletelabel = (!add->deletelabel) ? base->deletelabel : add->deletelabel;

    return new;
}

/**
 * Sanity check a given string that it exists, is not empty,
 * and does not contain special characters.
 */
static const char *check_string(cmd_parms * cmd, const char *string)
{
    if (APR_SUCCESS != ap_cookie_check_string(string)) {
        return apr_pstrcat(cmd->pool, cmd->directive->directive,
                           " cannot be empty, or contain '=', ';' or '&'.",
                           NULL);
    }
    return NULL;
}

static const char *
     set_dbd_peruser(cmd_parms * parms, void *dconf, int flag)
{
    session_dbd_dir_conf *conf = dconf;

    conf->peruser = flag;
    conf->peruser_set = 1;

    return NULL;
}

static const char *
     set_dbd_cookie_remove(cmd_parms * parms, void *dconf, int flag)
{
    session_dbd_dir_conf *conf = dconf;

    conf->remove = flag;
    conf->remove_set = 1;

    return NULL;
}

static const char *set_cookie_name(cmd_parms * cmd, void *config, const char *args)
{
    char *last;
    char *line = apr_pstrdup(cmd->pool, args);
    session_dbd_dir_conf *conf = (session_dbd_dir_conf *) config;
    char *cookie = apr_strtok(line, " \t", &last);
    conf->name = cookie;
    conf->name_set = 1;
    while (apr_isspace(*last)) {
        last++;
    }
    conf->name_attrs = last;
    return check_string(cmd, cookie);
}

static const char *set_cookie_name2(cmd_parms * cmd, void *config, const char *args)
{
    char *last;
    char *line = apr_pstrdup(cmd->pool, args);
    session_dbd_dir_conf *conf = (session_dbd_dir_conf *) config;
    char *cookie = apr_strtok(line, " \t", &last);
    conf->name2 = cookie;
    conf->name2_set = 1;
    while (apr_isspace(*last)) {
        last++;
    }
    conf->name2_attrs = last;
    return check_string(cmd, cookie);
}

static const command_rec session_dbd_cmds[] =
{
    AP_INIT_TAKE1("SessionDBDSelectLabel", ap_set_string_slot,
      (void *) APR_OFFSETOF(session_dbd_dir_conf, selectlabel), RSRC_CONF|OR_AUTHCFG,
                  "Query label used to select a new session"),
    AP_INIT_TAKE1("SessionDBDInsertLabel", ap_set_string_slot,
      (void *) APR_OFFSETOF(session_dbd_dir_conf, insertlabel), RSRC_CONF|OR_AUTHCFG,
                  "Query label used to insert a new session"),
    AP_INIT_TAKE1("SessionDBDUpdateLabel", ap_set_string_slot,
      (void *) APR_OFFSETOF(session_dbd_dir_conf, updatelabel), RSRC_CONF|OR_AUTHCFG,
                  "Query label used to update an existing session"),
    AP_INIT_TAKE1("SessionDBDDeleteLabel", ap_set_string_slot,
      (void *) APR_OFFSETOF(session_dbd_dir_conf, deletelabel), RSRC_CONF|OR_AUTHCFG,
                  "Query label used to delete an existing session"),
    AP_INIT_FLAG("SessionDBDPerUser", set_dbd_peruser, NULL, RSRC_CONF|OR_AUTHCFG,
                 "Save the session per user"),
    AP_INIT_FLAG("SessionDBDCookieRemove", set_dbd_cookie_remove, NULL, RSRC_CONF|OR_AUTHCFG,
                 "Remove the session cookie after session load. On by default."),
    AP_INIT_RAW_ARGS("SessionDBDCookieName", set_cookie_name, NULL, RSRC_CONF|OR_AUTHCFG,
                 "The name of the RFC2109 cookie carrying the session key"),
    AP_INIT_RAW_ARGS("SessionDBDCookieName2", set_cookie_name2, NULL, RSRC_CONF|OR_AUTHCFG,
                 "The name of the RFC2965 cookie carrying the session key"),
    {NULL}
};

static void register_hooks(apr_pool_t * p)
{
    ap_hook_session_load(session_dbd_load, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_session_save(session_dbd_save, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_monitor(session_dbd_monitor, NULL, NULL, APR_HOOK_MIDDLE);
}

AP_DECLARE_MODULE(session_dbd) =
{
    STANDARD20_MODULE_STUFF,
    create_session_dbd_dir_config, /* dir config creater */
    merge_session_dbd_dir_config,  /* dir merger --- default is to
                                    * override */
    NULL,                          /* server config */
    NULL,                          /* merge server config */
    session_dbd_cmds,              /* command apr_table_t */
    register_hooks                 /* register hooks */
};
