/* 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 "apr_private.h"

#if APU_HAVE_SQLITE2

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

#include <sqlite.h>

#include "apr_strings.h"
#include "apr_time.h"
#include "apr_buckets.h"

#include "apr_dbd_internal.h"

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

struct apr_dbd_t {
    sqlite *conn;
    char *errmsg;
    apr_dbd_transaction_t *trans;
};

struct apr_dbd_results_t {
    int random;
    sqlite *handle;
    char **res;
    size_t ntuples;
    size_t sz;
    size_t index;
    apr_pool_t *pool;
};

struct apr_dbd_row_t {
    int n;
    char **data;
    apr_dbd_results_t *res;
};

struct apr_dbd_prepared_t {
    const char *name;
    int prepared;
};

#define FREE_ERROR_MSG(dbd) \
	do { \
		if(dbd && dbd->errmsg) { \
			free(dbd->errmsg); \
			dbd->errmsg = NULL; \
		} \
	} while(0);

static apr_status_t free_table(void *data)
{
    sqlite_free_table(data); 
    return APR_SUCCESS;
}

static int dbd_sqlite_select(apr_pool_t * pool, apr_dbd_t * sql,
                             apr_dbd_results_t ** results, const char *query,
                             int seek)
{
    char **result;
    int ret = 0;
    int tuples = 0;
    int fields = 0;

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

    FREE_ERROR_MSG(sql);

    ret = sqlite_get_table(sql->conn, query, &result, &tuples, &fields,
                          &sql->errmsg);

    if (ret == SQLITE_OK) {
        if (!*results) {
            *results = apr_pcalloc(pool, sizeof(apr_dbd_results_t));
        }

        (*results)->res = result;
        (*results)->ntuples = tuples;
        (*results)->sz = fields;
        (*results)->random = seek;
        (*results)->pool = pool;

        if (tuples > 0)
            apr_pool_cleanup_register(pool, result, free_table,
                                      apr_pool_cleanup_null);

        ret = 0;
    }
    else {
        if (TXN_NOTICE_ERRORS(sql->trans)) {
            sql->trans->errnum = ret;
        }
    }

    return ret;
}

static const char *dbd_sqlite_get_name(const apr_dbd_results_t *res, int n)
{
    if ((n < 0) || (n >= res->sz)) {
        return NULL;
    }

    return res->res[n];
}

static int dbd_sqlite_get_row(apr_pool_t * pool, apr_dbd_results_t * res,
                              apr_dbd_row_t ** rowp, int rownum)
{
    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;
        row->n = sequential ? 0 : rownum - 1;
    }
    else {
        if (sequential) {
            ++row->n;
        }
        else {
            row->n = rownum - 1;
        }
    }

    if (row->n >= res->ntuples) {
        *rowp = NULL;
        apr_pool_cleanup_run(res->pool, res->res, free_table);
        res->res = NULL;
        return -1;
    }

    /* Pointer magic explanation:
     *      The sqlite result is an array such that the first res->sz elements are 
     *      the column names and each tuple follows afterwards 
     *      ex: (from the sqlite2 documentation)
     SELECT employee_name, login, host FROM users WHERE login LIKE *        'd%';

     nrow = 2
     ncolumn = 3
     result[0] = "employee_name"
     result[1] = "login"
     result[2] = "host"
     result[3] = "dummy"
     result[4] = "No such user"
     result[5] = 0
     result[6] = "D. Richard Hipp"
     result[7] = "drh"
     result[8] = "zadok"
     */

    row->data = res->res + res->sz + (res->sz * row->n);

    return 0;
}

static const char *dbd_sqlite_get_entry(const apr_dbd_row_t * row, int n)
{
    if ((n < 0) || (n >= row->res->sz)) {
      return NULL;
    }

    return row->data[n];
}

static apr_status_t dbd_sqlite_datum_get(const apr_dbd_row_t *row, int n,
                                         apr_dbd_type_e type, void *data)
{
    if ((n < 0) || (n >= row->res->sz)) {
      return APR_EGENERAL;
    }

    if (row->data[n] == NULL) {
        return APR_ENOENT;
    }

    switch (type) {
    case APR_DBD_TYPE_TINY:
        *(char*)data = atoi(row->data[n]);
        break;
    case APR_DBD_TYPE_UTINY:
        *(unsigned char*)data = atoi(row->data[n]);
        break;
    case APR_DBD_TYPE_SHORT:
        *(short*)data = atoi(row->data[n]);
        break;
    case APR_DBD_TYPE_USHORT:
        *(unsigned short*)data = atoi(row->data[n]);
        break;
    case APR_DBD_TYPE_INT:
        *(int*)data = atoi(row->data[n]);
        break;
    case APR_DBD_TYPE_UINT:
        *(unsigned int*)data = atoi(row->data[n]);
        break;
    case APR_DBD_TYPE_LONG:
        *(long*)data = atol(row->data[n]);
        break;
    case APR_DBD_TYPE_ULONG:
        *(unsigned long*)data = atol(row->data[n]);
        break;
    case APR_DBD_TYPE_LONGLONG:
        *(apr_int64_t*)data = apr_atoi64(row->data[n]);
        break;
    case APR_DBD_TYPE_ULONGLONG:
        *(apr_uint64_t*)data = apr_atoi64(row->data[n]);
        break;
    case APR_DBD_TYPE_FLOAT:
        *(float*)data = atof(row->data[n]);
        break;
    case APR_DBD_TYPE_DOUBLE:
        *(double*)data = atof(row->data[n]);
        break;
    case APR_DBD_TYPE_STRING:
    case APR_DBD_TYPE_TEXT:
    case APR_DBD_TYPE_TIME:
    case APR_DBD_TYPE_DATE:
    case APR_DBD_TYPE_DATETIME:
    case APR_DBD_TYPE_TIMESTAMP:
    case APR_DBD_TYPE_ZTIMESTAMP:
        *(char**)data = row->data[n];
        break;
    case APR_DBD_TYPE_BLOB:
    case APR_DBD_TYPE_CLOB:
        {
        apr_bucket *e;
        apr_bucket_brigade *b = (apr_bucket_brigade*)data;

        e = apr_bucket_pool_create(row->data[n],strlen(row->data[n]),
                                   row->res->pool, b->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(b, e);
        }
        break;
    case APR_DBD_TYPE_NULL:
        *(void**)data = NULL;
        break;
    default:
        return APR_EGENERAL;
    }

    return APR_SUCCESS;
}

static const char *dbd_sqlite_error(apr_dbd_t * sql, int n)
{
    return sql->errmsg;
}

static int dbd_sqlite_query(apr_dbd_t * sql, int *nrows, const char *query)
{
    char **result;
    int ret;
    int tuples = 0;
    int fields = 0;

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

    FREE_ERROR_MSG(sql);

    ret =
        sqlite_get_table(sql->conn, query, &result, &tuples, &fields,
                         &sql->errmsg);
    if (ret == SQLITE_OK) {
        *nrows = sqlite_changes(sql->conn);

        if (tuples > 0)
            free(result);

        ret = 0;
    }

    if (TXN_NOTICE_ERRORS(sql->trans)) {
        sql->trans->errnum = ret;
    }

    return ret;
}

static apr_status_t free_mem(void *data)
{
    sqlite_freemem(data);
    return APR_SUCCESS;
}

static const char *dbd_sqlite_escape(apr_pool_t * pool, const char *arg,
                                     apr_dbd_t * sql)
{
    char *ret = sqlite_mprintf("%q", arg);
    apr_pool_cleanup_register(pool, ret, free_mem, apr_pool_cleanup_null);
    return ret;
}

static int dbd_sqlite_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)
{
    return APR_ENOTIMPL;
}

static int dbd_sqlite_pquery(apr_pool_t * pool, apr_dbd_t * sql,
                             int *nrows, apr_dbd_prepared_t * statement,
                             const char **values)
{
    return APR_ENOTIMPL;
}

static int dbd_sqlite_pvquery(apr_pool_t * pool, apr_dbd_t * sql,
                              int *nrows, apr_dbd_prepared_t * statement,
                              va_list args)
{
    return APR_ENOTIMPL;
}

static int dbd_sqlite_pselect(apr_pool_t * pool, apr_dbd_t * sql,
                              apr_dbd_results_t ** results,
                              apr_dbd_prepared_t * statement,
                              int seek, const char **values)
{
    return APR_ENOTIMPL;
}

static int dbd_sqlite_pvselect(apr_pool_t * pool, apr_dbd_t * sql,
                               apr_dbd_results_t ** results,
                               apr_dbd_prepared_t * statement, int seek,
                               va_list args)
{
    return APR_ENOTIMPL;
}

static int dbd_sqlite_pbquery(apr_pool_t * pool, apr_dbd_t * sql,
                              int *nrows, apr_dbd_prepared_t * statement,
                              const void **values)
{
    return APR_ENOTIMPL;
}

static int dbd_sqlite_pvbquery(apr_pool_t * pool, apr_dbd_t * sql,
                               int *nrows, apr_dbd_prepared_t * statement,
                               va_list args)
{
    return APR_ENOTIMPL;
}

static int dbd_sqlite_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 APR_ENOTIMPL;
}

static int dbd_sqlite_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 APR_ENOTIMPL;
}

static int dbd_sqlite_start_transaction(apr_pool_t * pool, apr_dbd_t * handle,
                                        apr_dbd_transaction_t ** trans)
{
    int ret, rows;

    ret = dbd_sqlite_query(handle, &rows, "BEGIN TRANSACTION");
    if (ret == 0) {
        if (!*trans) {
            *trans = apr_pcalloc(pool, sizeof(apr_dbd_transaction_t));
        }
        (*trans)->handle = handle;
        handle->trans = *trans;
    }
    else {
        ret = -1;
    }
    return ret;
}

static int dbd_sqlite_end_transaction(apr_dbd_transaction_t * trans)
{
    int rows;
    int ret = -1;               /* no transaction is an error cond */

    if (trans) {
        /* rollback on error or explicit rollback request */
        if (trans->errnum || TXN_DO_ROLLBACK(trans)) {
            trans->errnum = 0;
            ret =
                dbd_sqlite_query(trans->handle, &rows,
                                 "ROLLBACK TRANSACTION");
        }
        else {
            ret =
                dbd_sqlite_query(trans->handle, &rows, "COMMIT TRANSACTION");
        }
        trans->handle->trans = NULL;
    }

    return ret;
}

static int dbd_sqlite_transaction_mode_get(apr_dbd_transaction_t *trans)
{
    if (!trans)
        return APR_DBD_TRANSACTION_COMMIT;

    return trans->mode;
}

static int dbd_sqlite_transaction_mode_set(apr_dbd_transaction_t *trans,
                                           int mode)
{
    if (!trans)
        return APR_DBD_TRANSACTION_COMMIT;

    return trans->mode = (mode & TXN_MODE_BITS);
}

static apr_status_t error_free(void *data)
{
    free(data);
    return APR_SUCCESS;
}

static apr_dbd_t *dbd_sqlite_open(apr_pool_t * pool, const char *params_,
                                  const char **error)
{
    apr_dbd_t *sql;
    sqlite *conn = NULL;
    char *perm;
    int iperms = 600;
    char* params = apr_pstrdup(pool, params_);
    /* params = "[filename]:[permissions]"
     *    example: "shopping.db:600"
     */

    perm = strstr(params, ":");
    if (perm) {
        *(perm++) = '\x00';     /* split the filename and permissions */

        if (strlen(perm) > 0)
            iperms = atoi(perm);
    }

    if (error) {
        *error = NULL;

        conn = sqlite_open(params, iperms, (char **)error);

        if (*error) {
            apr_pool_cleanup_register(pool, *error, error_free,
                                      apr_pool_cleanup_null);
        }
    }
    else {
        conn = sqlite_open(params, iperms, NULL);
    }

    sql = apr_pcalloc(pool, sizeof(*sql));
    sql->conn = conn;

    return sql;
}

static apr_status_t dbd_sqlite_close(apr_dbd_t * handle)
{
    if (handle->conn) {
        sqlite_close(handle->conn);
        handle->conn = NULL;
    }
    return APR_SUCCESS;
}

static apr_status_t dbd_sqlite_check_conn(apr_pool_t * pool,
                                          apr_dbd_t * handle)
{
    if (handle->conn == NULL)
        return -1;
    return APR_SUCCESS;
}

static int dbd_sqlite_select_db(apr_pool_t * pool, apr_dbd_t * handle,
                                const char *name)
{
    return APR_ENOTIMPL;
}

static void *dbd_sqlite_native(apr_dbd_t * handle)
{
    return handle->conn;
}

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

static int dbd_sqlite_num_tuples(apr_dbd_results_t * res)
{
    return res->ntuples;
}

APR_MODULE_DECLARE_DATA const apr_dbd_driver_t apr_dbd_sqlite2_driver = {
    "sqlite2",
    NULL,
    dbd_sqlite_native,
    dbd_sqlite_open,
    dbd_sqlite_check_conn,
    dbd_sqlite_close,
    dbd_sqlite_select_db,
    dbd_sqlite_start_transaction,
    dbd_sqlite_end_transaction,
    dbd_sqlite_query,
    dbd_sqlite_select,
    dbd_sqlite_num_cols,
    dbd_sqlite_num_tuples,
    dbd_sqlite_get_row,
    dbd_sqlite_get_entry,
    dbd_sqlite_error,
    dbd_sqlite_escape,
    dbd_sqlite_prepare,
    dbd_sqlite_pvquery,
    dbd_sqlite_pvselect,
    dbd_sqlite_pquery,
    dbd_sqlite_pselect,
    dbd_sqlite_get_name,
    dbd_sqlite_transaction_mode_get,
    dbd_sqlite_transaction_mode_set,
    NULL,
    dbd_sqlite_pvbquery,
    dbd_sqlite_pvbselect,
    dbd_sqlite_pbquery,
    dbd_sqlite_pbselect,
    dbd_sqlite_datum_get
};
#endif
