/* 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);

    fprintf(stderr, "databaseName [%s]\n", databaseName);

    if (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 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();
    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
