/* 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 "apu.h"
#include "apu_config.h"

/* COMPILE_STUBS: compile stubs for unimplemented functions.
 *
 * This is required to compile in /trunk/, but can be
 * undefined to compile a driver for httpd-2.2 and other
 * APR-1.2 applications
 */
#define COMPILE_STUBS

#if APU_HAVE_FREETDS

#include <ctype.h>
#include <stdlib.h>

#include "apr_strings.h"
#include "apr_lib.h"

#include "apr_pools.h"
#include "apr_dbd_internal.h"

#ifdef HAVE_FREETDS_SYBDB_H
#include <freetds/sybdb.h>
#endif
#ifdef HAVE_SYBDB_H
#include <sybdb.h>
#endif

#include <stdio.h>
#include <sys/types.h>
#include <regex.h>

/* This probably needs to change for different applications */
#define MAX_COL_LEN 256

typedef struct freetds_cell_t {
    int type;
    DBINT len;
    BYTE *data;
} freetds_cell_t;

struct apr_dbd_transaction_t {
    int mode;
    int errnum;
    apr_dbd_t *handle;
};

struct apr_dbd_t {
    DBPROCESS *proc;
    apr_dbd_transaction_t *trans;
    apr_pool_t *pool;
    const char *params;
    RETCODE err;
};

struct apr_dbd_results_t {
    int random;
    size_t ntuples;
    size_t sz;
    apr_pool_t *pool;
    DBPROCESS *proc;
};

struct apr_dbd_row_t {
    apr_dbd_results_t *res;
    BYTE buf[MAX_COL_LEN];
};

struct apr_dbd_prepared_t {
    int nargs;
    regex_t **taint;
    int *sz;
    char *fmt;
};

#define dbd_freetds_is_success(x) (x == SUCCEED)

static int labelnum = 0; /* FIXME */
static regex_t dbd_freetds_find_arg;

/* execute a query that doesn't return a result set, mop up,
 * and return and APR-flavoured status
 */
static RETCODE freetds_exec(DBPROCESS *proc, const char *query,
                            int want_results, int *nrows)
{
    /* TBD */
    RETCODE rv = dbcmd(proc, query);
    if (rv != SUCCEED) {
        return rv;
    }
    rv = dbsqlexec(proc);
    if (rv != SUCCEED) {
        return rv;
    }
    if (!want_results) {
        while (dbresults(proc) != NO_MORE_RESULTS) {
            ++*nrows;
        }
    }
    return SUCCEED;
}
static apr_status_t clear_result(void *data)
{
    /* clear cursor */
    return (dbcanquery((DBPROCESS*)data) == SUCCEED)
            ? APR_SUCCESS
            : APR_EGENERAL;
}

static int dbd_freetds_select(apr_pool_t *pool, apr_dbd_t *sql,
                              apr_dbd_results_t **results,
                              const char *query, int seek)
{
    apr_dbd_results_t *res;
    if (sql->trans && (sql->trans->errnum != SUCCEED)) {
        return 1;
    }
    /* the core of this is
     * dbcmd(proc, query);
     * dbsqlexec(proc);
     * while (dbnextrow(dbproc) != NO_MORE_ROWS) {
     *     do things
     * }
     *
     * Ignore seek
     */

    sql->err = freetds_exec(sql->proc, query, 1, NULL);
    if (!dbd_freetds_is_success(sql->err)) {
        if (sql->trans) {
            sql->trans->errnum = sql->err;
        }
        return 1;
    }

    sql->err = dbresults(sql->proc);
    if (sql->err != SUCCEED) {
        if (sql->trans) {
            sql->trans->errnum = sql->err;
        }
        return 1;
    }

    if (!*results) {
        *results = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
    }
    res = *results;
    res->proc = sql->proc;
    res->random = seek;
    res->pool = pool;
    res->ntuples = dblastrow(sql->proc);
    res->sz = dbnumcols(sql->proc);
    apr_pool_cleanup_register(pool, sql->proc, clear_result,
                              apr_pool_cleanup_null);

#if 0
    /* Now we have a result set.  We need to bind to its vars */
    res->vars = apr_palloc(pool, res->sz * sizeof(freetds_cell_t*));
    for (i=1; i <= res->sz; ++i) {
        freetds_cell_t *cell = &res->vars[i-1];
        cell->type = dbcoltype(sql->proc, i);
        cell->len = dbcollen(sql->proc, i);
        cell->data = apr_palloc(pool, cell->len);
        sql->err = dbbind(sql->proc, i, /*cell->type */ STRINGBIND, cell->len, cell->data);
        if (sql->err != SUCCEED) {
            fprintf(stderr, "dbbind error: %d, %d, %d", i, cell->type, cell->len);
        }
        if ((sql->err != SUCCEED) && (sql->trans != NULL)) {
            sql->trans->errnum = sql->err;
        }
    }
#endif
    return (sql->err == SUCCEED) ? 0 : 1;
}
static const char *dbd_untaint(apr_pool_t *pool, regex_t *rx, const char *val)
{
    regmatch_t match[1];
    if (rx == NULL) {
        /* no untaint expression */
        return val;
    }
    if (regexec(rx, val, 1, match, 0) == 0) {
        return apr_pstrndup(pool, val+match[0].rm_so,
                            match[0].rm_eo - match[0].rm_so);
    }
    return "";
}
static const char *dbd_statement(apr_pool_t *pool,
                                 apr_dbd_prepared_t *stmt,
                                 int nargs, const char **args)
{
    int i;
    int len;
    const char *var;
    char *ret;
    const char *p_in;
    char *p_out;
    char *q;
   
    /* compute upper bound on length (since untaint shrinks) */
    len  = strlen(stmt->fmt) +1;
    for (i=0; i<nargs; ++i) {
        len += strlen(args[i]) - 2;
    }
    i = 0;
    p_in = stmt->fmt;
    p_out = ret = apr_palloc(pool, len);
    /* FIXME silly bug - this'll catch %%s */
    while (q = strstr(p_in, "%s"), q != NULL) {
        len = q-p_in;
        strncpy(p_out, p_in, len);
        p_in += len;
        p_out += len;
        var = dbd_untaint(pool, stmt->taint[i], args[i]);
        len = strlen(var);
        strncpy(p_out, var, len);
        p_in += 2;
        p_out += len;
        ++i;
    }
    strcpy(p_out, p_in);
    return ret;
}
static int dbd_freetds_pselect(apr_pool_t *pool, apr_dbd_t *sql,
                               apr_dbd_results_t **results,
                               apr_dbd_prepared_t *statement,
                               int seek, const char **values)
{
    const char *query = dbd_statement(pool, statement,
                                      statement->nargs, values);
    return dbd_freetds_select(pool, sql, results, query, seek);
}
static int dbd_freetds_pvselect(apr_pool_t *pool, apr_dbd_t *sql,
                                apr_dbd_results_t **results,
                                apr_dbd_prepared_t *statement,
                                int seek, va_list args)
{
    const char **values;
    int i;

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

    values = apr_palloc(pool, sizeof(*values) * statement->nargs);

    for (i = 0; i < statement->nargs; i++) {
        values[i] = va_arg(args, const char*);
    }

    return dbd_freetds_pselect(pool, sql, results, statement, seek, values);
}
static int dbd_freetds_query(apr_dbd_t *sql, int *nrows, const char *query);
static int dbd_freetds_pquery(apr_pool_t *pool, apr_dbd_t *sql,
                              int *nrows, apr_dbd_prepared_t *statement,
                              const char **values)
{
    const char *query = dbd_statement(pool, statement,
                                      statement->nargs, values);
    return dbd_freetds_query(sql, nrows, query);
}
static int dbd_freetds_pvquery(apr_pool_t *pool, apr_dbd_t *sql, int *nrows,
                               apr_dbd_prepared_t *statement, va_list args)
{
    const char **values;
    int i;

    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }

    values = apr_palloc(pool, sizeof(*values) * statement->nargs);

    for (i = 0; i < statement->nargs; i++) {
        values[i] = va_arg(args, const char*);
    }
    return dbd_freetds_pquery(pool, sql, nrows, statement, values);
}

static int dbd_freetds_get_row(apr_pool_t *pool, apr_dbd_results_t *res,
                               apr_dbd_row_t **rowp, int rownum)
{
    RETCODE rv = 0;
    apr_dbd_row_t *row = *rowp;
    int sequential = ((rownum >= 0) && res->random) ? 0 : 1;

    if (row == NULL) {
        row = apr_palloc(pool, sizeof(apr_dbd_row_t));
        *rowp = row;
        row->res = res;
    }
    /*
    else {
        if ( sequential ) {
            ++row->n;
        }
        else {
            row->n = rownum;
        }
    }
    */
    if (sequential) {
        rv = dbnextrow(res->proc);
    }
    else {
        rv = (rownum >= 0) ? dbgetrow(res->proc, rownum) : NO_MORE_ROWS;
    }
    switch (rv) {
    case SUCCEED: return 0;
    case REG_ROW: return 0;
    case NO_MORE_ROWS:
        apr_pool_cleanup_run(pool, res->proc, clear_result);
        *rowp = NULL;
        return -1;
    case FAIL: return 1;
    case BUF_FULL: return 2; /* FIXME */
    default: return 3;
    }

    return 0;
}

static const char *dbd_freetds_get_entry(const apr_dbd_row_t *row, int n)
{
    /* FIXME: support different data types */
    /* this fails - bind gets some vars but not others
    return (const char*)row->res->vars[n].data;
     */
    DBPROCESS* proc = row->res->proc;
    BYTE *ptr = dbdata(proc, n+1);
    int t = dbcoltype(proc, n+1);
    int l = dbcollen(proc, n+1);
    if (dbwillconvert(t, SYBCHAR)) {
      dbconvert(proc, t, ptr, l, SYBCHAR, (BYTE *)row->buf, -1);
      return (const char*)row->buf;
    }
    return (char*)ptr;
}

static const char *dbd_freetds_error(apr_dbd_t *sql, int n)
{
    /* XXX this doesn't seem to exist in the API ??? */
    return apr_psprintf(sql->pool, "Error %d", sql->err);
}

static int dbd_freetds_query(apr_dbd_t *sql, int *nrows, const char *query)
{
    if (sql->trans && sql->trans->errnum) {
        return sql->trans->errnum;
    }
    *nrows = 0;
    sql->err = freetds_exec(sql->proc, query, 0, nrows);

    if (sql->err != SUCCEED) {
        if (sql->trans) {
            sql->trans->errnum = sql->err;
        }
        return 1;
    }
    return 0;
}

static const char *dbd_freetds_escape(apr_pool_t *pool, const char *arg,
                                      apr_dbd_t *sql)
{
    return arg;
}

static apr_status_t freetds_regfree(void *rx)
{
    regfree((regex_t*)rx);
    return APR_SUCCESS;
}
static int recurse_args(apr_pool_t *pool, int n, const char *query,
                        apr_dbd_prepared_t *stmt, int offs)
{

    /* we only support %s arguments for now */
    int ret;
    char arg[256];
    regmatch_t matches[3];
    if (regexec(&dbd_freetds_find_arg, query, 3, matches, 0) != 0) {
        /* No more args */
        stmt->nargs = n;
        stmt->taint = apr_palloc(pool, n*sizeof(regex_t*));
        stmt->sz = apr_palloc(pool, n*sizeof(int));
        ret = 0;
    }
    else {
        int i;
        int sz = 0;
        int len = matches[1].rm_eo - matches[1].rm_so - 2;
        if (len > 255) {
            return 9999;
        }

        ret = recurse_args(pool, n+1, query+matches[0].rm_eo,
                           stmt, offs+matches[0].rm_eo);

        memmove(stmt->fmt + offs + matches[1].rm_so,
                stmt->fmt + offs + matches[0].rm_eo-1,
                strlen(stmt->fmt+offs+matches[0].rm_eo)+2);

        /* compile untaint to a regex if found */
        if (matches[1].rm_so == -1) {
            stmt->taint[n] = NULL;
        }
        else {
            strncpy(arg, query+matches[1].rm_so+1,
                    matches[1].rm_eo - matches[1].rm_so - 2);
            arg[matches[1].rm_eo - matches[1].rm_so - 2] = '\0';
            stmt->taint[n] = apr_palloc(pool, sizeof(regex_t));
            if (regcomp(stmt->taint[n], arg, REG_ICASE|REG_EXTENDED) != 0) {
                ++ret;
            }
            else {
                apr_pool_cleanup_register(pool, stmt->taint[n], freetds_regfree,
                                          apr_pool_cleanup_null);
            }
        }

        /* record length if specified */
        for (i=matches[2].rm_so; i<matches[2].rm_eo; ++i) {
            sz = 10*sz + (query[i]-'\0');
        }
    }
    return ret;
}

static int dbd_freetds_prepare(apr_pool_t *pool, apr_dbd_t *sql,
                             const char *query, const char *label,
                             int nargs, int nvals, apr_dbd_type_e *types,
                             apr_dbd_prepared_t **statement)
{
    apr_dbd_prepared_t *stmt;

    if (label == NULL) {
        label = apr_psprintf(pool, "%d", labelnum++);
    }

    if (!*statement) {
        *statement = apr_palloc(pool, sizeof(apr_dbd_prepared_t));
    }
    stmt = *statement;

#if 0
    /* count args */
    stmt->fmt = apr_pstrdup(pool, query);
    stmt->fmt = recurse_args(pool, 0, query, stmt, stmt->fmt);

    /* overestimate by a byte or two to simplify */
    len = strlen("CREATE PROC apr.")
            + strlen(label)
            + stmt->nargs * strlen(" @arg1 varchar(len1),")
            + strlen(" AS begin ")
            + strlen(stmt->fmt)
            + strlen(" end "); /* extra byte for terminator */

    pquery = apr_pcalloc(pool, len);
    sprintf(pquery, "CREATE PROC apr.%s", label);
    for (i=0; i<stmt->nargs; ++i) {
        sprintf(pquery+strlen(pquery), " @arg%d varchar(%d)", i, stmt->sz[i]);
        if (i < stmt->nargs-1) {
            pquery[strlen(pquery)] = ',';
        }
    }
    strcat(pquery, " AS BEGIN ");
    strcat(pquery, stmt->fmt);
    strcat(pquery, " END");

    return (freetds_exec(sql->proc, pquery, 0, &i) == SUCCEED) ? 0 : 1;
#else
    stmt->fmt = apr_pstrdup(pool, query);
    return recurse_args(pool, 0, query, stmt, 0);
#endif

}

static int dbd_freetds_start_transaction(apr_pool_t *pool, apr_dbd_t *handle,
                                         apr_dbd_transaction_t **trans)
{
    int dummy;

    /* XXX handle recursive transactions here */

    handle->err = freetds_exec(handle->proc, "BEGIN TRANSACTION", 0, &dummy);

    if (dbd_freetds_is_success(handle->err)) {
        if (!*trans) {
            *trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t));
        }
        (*trans)->handle = handle;
        handle->trans = *trans;
        return 0;
    }

    return 1;
}

static int dbd_freetds_end_transaction(apr_dbd_transaction_t *trans)
{
    int dummy;
    if (trans) {
        /* rollback on error or explicit rollback request */
        if (trans->errnum) {
            trans->errnum = 0;
            trans->handle->err = freetds_exec(trans->handle->proc,
                                              "ROLLBACK", 0, &dummy);
        }
        else {
            trans->handle->err = freetds_exec(trans->handle->proc,
                                              "COMMIT", 0, &dummy);
        }
        trans->handle->trans = NULL;
    }
    return (trans->handle->err == SUCCEED) ? 0 : 1;
}

static DBPROCESS *freetds_open(apr_pool_t *pool, const char *params,
                               const char **error)
{
    char *server = NULL;
    DBPROCESS *process;
    LOGINREC *login;
    static const char *delims = " \r\n\t;|,";
    char *ptr;
    char *key;
    char *value;
    int vlen;
    int klen;
    char *buf;
    char *databaseName = NULL;

    /* FIXME - this uses malloc */
    /* FIXME - pass error message back to the caller in case of failure */
    login = dblogin();
    if (login == NULL) {
        return NULL;
    }
    /* now set login properties */
    for (ptr = strchr(params, '='); ptr; ptr = strchr(ptr, '=')) {
        /* don't dereference memory that may not belong to us */
        if (ptr == params) {
            ++ptr;
            continue;
        }
        for (key = ptr-1; apr_isspace(*key); --key);
        klen = 0;
        while (apr_isalpha(*key)) {
            --key;
            ++klen;
        }
        ++key;
        for (value = ptr+1; apr_isspace(*value); ++value);

        vlen = strcspn(value, delims);
        buf = apr_pstrndup(pool, value, vlen);        /* NULL-terminated copy */

        if (!strncasecmp(key, "username", klen)) {
            DBSETLUSER(login, buf);
        }
        else if (!strncasecmp(key, "password", klen)) {
            DBSETLPWD(login, buf);
        }
        else if (!strncasecmp(key, "appname", klen)) {
            DBSETLAPP(login, buf);
        }
        else if (!strncasecmp(key, "dbname", klen)) {
            databaseName = buf;
        }
        else if (!strncasecmp(key, "host", klen)) {
            DBSETLHOST(login, buf);
        }
        else if (!strncasecmp(key, "charset", klen)) {
            DBSETLCHARSET(login, buf);
        }
        else if (!strncasecmp(key, "lang", klen)) {
            DBSETLNATLANG(login, buf);
        }
        else if (!strncasecmp(key, "server", klen)) {
            server = buf;
        }
        else {
            /* unknown param */
        }
        ptr = value+vlen;
    }

    process = dbopen(login, server);

    if (process != NULL && databaseName != NULL)
    {
        dbuse(process, databaseName);
    }
 
    dbloginfree(login);
    if (process == NULL) {
        return NULL;
    }

    return process;
}
static apr_dbd_t *dbd_freetds_open(apr_pool_t *pool, const char *params,
                                   const char **error)
{
    apr_dbd_t *sql;
    /* FIXME - pass error message back to the caller in case of failure */
    DBPROCESS *process = freetds_open(pool, params, error);
    if (process == NULL) {
        return NULL;
    }
    sql = apr_palloc (pool, sizeof (apr_dbd_t));
    sql->pool = pool;
    sql->proc = process;
    sql->params = params;
    return sql;
}

static apr_status_t dbd_freetds_close(apr_dbd_t *handle)
{
    dbclose(handle->proc);
    return APR_SUCCESS;
}

static apr_status_t dbd_freetds_check_conn(apr_pool_t *pool,
                                           apr_dbd_t *handle)
{
    if (dbdead(handle->proc)) {
        /* try again */
        dbclose(handle->proc);
        handle->proc = freetds_open(handle->pool, handle->params, NULL);
        if (!handle->proc || dbdead(handle->proc)) {
            return APR_EGENERAL;
        }
    }
    /* clear it, in case this is called in error handling */
    dbcancel(handle->proc);
    return APR_SUCCESS;
}

static int dbd_freetds_select_db(apr_pool_t *pool, apr_dbd_t *handle,
                               const char *name)
{
    /* ouch, it's declared int.  But we can use APR 0/nonzero */
    return (dbuse(handle->proc, (char*)name) == SUCCEED) ? APR_SUCCESS : APR_EGENERAL;
}

static void *dbd_freetds_native(apr_dbd_t *handle)
{
    return handle->proc;
}

static int dbd_freetds_num_cols(apr_dbd_results_t* res)
{
    return res->sz;
}

static int dbd_freetds_num_tuples(apr_dbd_results_t* res)
{
    if (res->random) {
        return res->ntuples;
    }
    else {
        return -1;
    }
}

static apr_status_t freetds_term(void *dummy)
{
    dbexit();
    regfree(&dbd_freetds_find_arg);
    return APR_SUCCESS;
}
static int freetds_err_handler(DBPROCESS *dbproc, int severity, int dberr,
                               int oserr, char *dberrstr, char *oserrstr)
{
    return INT_CANCEL; /* never exit */
}
static void dbd_freetds_init(apr_pool_t *pool)
{
    int rv = regcomp(&dbd_freetds_find_arg,
                     "%(\\{[^}]*\\})?([0-9]*)[A-Za-z]", REG_EXTENDED);
    if (rv != 0) {
        char errmsg[256];
        regerror(rv, &dbd_freetds_find_arg, errmsg, 256);
        fprintf(stderr, "regcomp failed: %s\n", errmsg);
    }
    dbinit();
    dberrhandle(freetds_err_handler);
    apr_pool_cleanup_register(pool, NULL, freetds_term, apr_pool_cleanup_null);
}

#ifdef COMPILE_STUBS
/* get_name is the only one of these that is implemented */
static const char *dbd_freetds_get_name(const apr_dbd_results_t *res, int n)
{
    return (const char*) dbcolname(res->proc, n+1); /* numbering starts at 1 */
}

/* These are stubs: transaction modes not implemented here */
#define DBD_NOTIMPL APR_ENOTIMPL;
static int dbd_freetds_transaction_mode_get(apr_dbd_transaction_t *trans)
{
    return trans ? trans->mode : APR_DBD_TRANSACTION_COMMIT;
}

static int dbd_freetds_transaction_mode_set(apr_dbd_transaction_t *trans,
                                            int mode)
{
    if (trans) {
        trans->mode = mode & TXN_MODE_BITS;
        return trans->mode;
    }
    return APR_DBD_TRANSACTION_COMMIT;
}
static int dbd_freetds_pvbquery(apr_pool_t *pool, apr_dbd_t *sql, int *nrows,
                                apr_dbd_prepared_t *statement, va_list args)
{
    return DBD_NOTIMPL;
}
static int dbd_freetds_pbquery(apr_pool_t *pool, apr_dbd_t *sql, int *nrows,
                               apr_dbd_prepared_t * statement,
                               const void **values)
{
    return DBD_NOTIMPL;
}

static int dbd_freetds_pvbselect(apr_pool_t *pool, apr_dbd_t *sql,
                                 apr_dbd_results_t **results,
                                 apr_dbd_prepared_t *statement,
                                 int seek, va_list args)
{
    return DBD_NOTIMPL;
}
static int dbd_freetds_pbselect(apr_pool_t *pool, apr_dbd_t *sql,
                                apr_dbd_results_t **results,
                                apr_dbd_prepared_t *statement,
                                int seek, const void **values)
{
    return DBD_NOTIMPL;
}
static apr_status_t dbd_freetds_datum_get(const apr_dbd_row_t *row, int n,
                                          apr_dbd_type_e type, void *data)
{
    return APR_ENOTIMPL;
}
#endif

APU_MODULE_DECLARE_DATA const apr_dbd_driver_t apr_dbd_freetds_driver = {
    "freetds",
    dbd_freetds_init,
    dbd_freetds_native,
    dbd_freetds_open,
    dbd_freetds_check_conn,
    dbd_freetds_close,
    dbd_freetds_select_db,
    dbd_freetds_start_transaction,
    dbd_freetds_end_transaction,
    dbd_freetds_query,
    dbd_freetds_select,
    dbd_freetds_num_cols,
    dbd_freetds_num_tuples,
    dbd_freetds_get_row,
    dbd_freetds_get_entry,
    dbd_freetds_error,
    dbd_freetds_escape,
    dbd_freetds_prepare,
    dbd_freetds_pvquery,
    dbd_freetds_pvselect,
    dbd_freetds_pquery,
    dbd_freetds_pselect,
    /* this is only implemented to support httpd/2.2 standard usage,
     * as in the original DBD implementation.  Everything else is NOTIMPL.
     */
#ifdef COMPILE_STUBS
    dbd_freetds_get_name,
    dbd_freetds_transaction_mode_get,
    dbd_freetds_transaction_mode_set,
    "",
    dbd_freetds_pvbquery,
    dbd_freetds_pvbselect,
    dbd_freetds_pbquery,
    dbd_freetds_pbselect,
    dbd_freetds_datum_get
#endif
};
#endif
