/* 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 "apr_memcache.h"
#include "apr_poll.h"
#include "apr_version.h"
#include <stdlib.h>

#define BUFFER_SIZE 512
struct apr_memcache_conn_t
{
    char *buffer;
    apr_size_t blen;
    apr_pool_t *p;
    apr_pool_t *tp;
    apr_socket_t *sock;
    apr_bucket_brigade *bb;
    apr_bucket_brigade *tb;
    apr_memcache_server_t *ms;
};                                                          

/* Strings for Client Commands */

#define MC_EOL "\r\n"
#define MC_EOL_LEN (sizeof(MC_EOL)-1)

#define MC_WS " "
#define MC_WS_LEN (sizeof(MC_WS)-1)

#define MC_GET "get "
#define MC_GET_LEN (sizeof(MC_GET)-1)

#define MC_SET "set "
#define MC_SET_LEN (sizeof(MC_SET)-1)

#define MC_ADD "add "
#define MC_ADD_LEN (sizeof(MC_ADD)-1)

#define MC_REPLACE "replace "
#define MC_REPLACE_LEN (sizeof(MC_REPLACE)-1)

#define MC_DELETE "delete "
#define MC_DELETE_LEN (sizeof(MC_DELETE)-1)

#define MC_INCR "incr "
#define MC_INCR_LEN (sizeof(MC_INCR)-1)

#define MC_DECR "decr "
#define MC_DECR_LEN (sizeof(MC_DECR)-1)

#define MC_VERSION "version"
#define MC_VERSION_LEN (sizeof(MC_VERSION)-1)

#define MC_STATS "stats"
#define MC_STATS_LEN (sizeof(MC_STATS)-1)

#define MC_QUIT "quit"
#define MC_QUIT_LEN (sizeof(MC_QUIT)-1)

/* Strings for Server Replies */

#define MS_STORED "STORED"
#define MS_STORED_LEN (sizeof(MS_STORED)-1)

#define MS_NOT_STORED "NOT_STORED"
#define MS_NOT_STORED_LEN (sizeof(MS_NOT_STORED)-1)

#define MS_DELETED "DELETED"
#define MS_DELETED_LEN (sizeof(MS_DELETED)-1)

#define MS_NOT_FOUND "NOT_FOUND"
#define MS_NOT_FOUND_LEN (sizeof(MS_NOT_FOUND)-1)

#define MS_VALUE "VALUE"
#define MS_VALUE_LEN (sizeof(MS_VALUE)-1)

#define MS_ERROR "ERROR"
#define MS_ERROR_LEN (sizeof(MS_ERROR)-1)

#define MS_VERSION "VERSION"
#define MS_VERSION_LEN (sizeof(MS_VERSION)-1)

#define MS_STAT "STAT"
#define MS_STAT_LEN (sizeof(MS_STAT)-1)

#define MS_END "END"
#define MS_END_LEN (sizeof(MS_END)-1)

/** Server and Query Structure for a multiple get */
struct cache_server_query_t {
    apr_memcache_server_t* ms;
    apr_memcache_conn_t* conn;
    struct iovec* query_vec;
    apr_int32_t query_vec_count;
};

#define MULT_GET_TIMEOUT 50000

static apr_status_t make_server_dead(apr_memcache_t *mc, apr_memcache_server_t *ms)
{
#if APR_HAS_THREADS
    apr_thread_mutex_lock(ms->lock);
#endif
    ms->status = APR_MC_SERVER_DEAD;
    ms->btime = apr_time_now();
#if APR_HAS_THREADS
    apr_thread_mutex_unlock(ms->lock);
#endif
    return APR_SUCCESS;
}

static apr_status_t make_server_live(apr_memcache_t *mc, apr_memcache_server_t *ms)
{
    ms->status = APR_MC_SERVER_LIVE; 
    return APR_SUCCESS;
}


APU_DECLARE(apr_status_t) apr_memcache_add_server(apr_memcache_t *mc, apr_memcache_server_t *ms)
{
    apr_status_t rv = APR_SUCCESS;

    if(mc->ntotal >= mc->nalloc) {
        return APR_ENOMEM;
    }

    mc->live_servers[mc->ntotal] = ms;
    mc->ntotal++;
    make_server_live(mc, ms);
    return rv;
}

static apr_status_t mc_version_ping(apr_memcache_server_t *ms);

APU_DECLARE(apr_memcache_server_t *) 
apr_memcache_find_server_hash(apr_memcache_t *mc, const apr_uint32_t hash)
{
    if (mc->server_func) {
        return mc->server_func(mc->server_baton, mc, hash);
    }
    else {
        return apr_memcache_find_server_hash_default(NULL, mc, hash);
    }
}   

APU_DECLARE(apr_memcache_server_t *) 
apr_memcache_find_server_hash_default(void *baton, apr_memcache_t *mc,
                                      const apr_uint32_t hash)
{
    apr_memcache_server_t *ms = NULL;
    apr_uint32_t h = hash ? hash : 1;
    apr_uint32_t i = 0;
    apr_time_t curtime = 0;
   
    if(mc->ntotal == 0) {
        return NULL;
    }

    do {
        ms = mc->live_servers[h % mc->ntotal];
        if(ms->status == APR_MC_SERVER_LIVE) {
            break;
        }
        else {
            if (curtime == 0) {
                curtime = apr_time_now();
            }
#if APR_HAS_THREADS
            apr_thread_mutex_lock(ms->lock);
#endif
            /* Try the the dead server, every 5 seconds */
            if (curtime - ms->btime >  apr_time_from_sec(5)) {
                if (mc_version_ping(ms) == APR_SUCCESS) {
                    ms->btime = curtime;
                    make_server_live(mc, ms);
#if APR_HAS_THREADS
                    apr_thread_mutex_unlock(ms->lock);
#endif
                    break;
                }
            }
#if APR_HAS_THREADS
            apr_thread_mutex_unlock(ms->lock);
#endif
        }
        h++;
        i++;
    } while(i < mc->ntotal);

    if (i == mc->ntotal) {
        ms = NULL;
    }

    return ms;
}

APU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server(apr_memcache_t *mc, const char *host, apr_port_t port)
{
    int i;

    for (i = 0; i < mc->ntotal; i++) {
        if (strcmp(mc->live_servers[i]->host, host) == 0
            && mc->live_servers[i]->port == port) {

            return mc->live_servers[i];
        }
    }

    return NULL;
}

static apr_status_t ms_find_conn(apr_memcache_server_t *ms, apr_memcache_conn_t **conn) 
{
    apr_status_t rv;
    apr_bucket_alloc_t *balloc;
    apr_bucket *e;

#if APR_HAS_THREADS
    rv = apr_reslist_acquire(ms->conns, (void **)conn);
#else
    *conn = ms->conn;
    rv = APR_SUCCESS;
#endif

    if (rv != APR_SUCCESS) {
        return rv;
    }

    balloc = apr_bucket_alloc_create((*conn)->tp);
    (*conn)->bb = apr_brigade_create((*conn)->tp, balloc);
    (*conn)->tb = apr_brigade_create((*conn)->tp, balloc);

    e = apr_bucket_socket_create((*conn)->sock, balloc);
    APR_BRIGADE_INSERT_TAIL((*conn)->bb, e);

    return rv;
}

static apr_status_t ms_bad_conn(apr_memcache_server_t *ms, apr_memcache_conn_t *conn) 
{
#if APR_HAS_THREADS
    return apr_reslist_invalidate(ms->conns, conn);
#else
    return APR_SUCCESS;
#endif
}

static apr_status_t ms_release_conn(apr_memcache_server_t *ms, apr_memcache_conn_t *conn) 
{
    apr_pool_clear(conn->tp);
#if APR_HAS_THREADS
    return apr_reslist_release(ms->conns, conn);
#else
    return APR_SUCCESS;
#endif
}

APU_DECLARE(apr_status_t) apr_memcache_enable_server(apr_memcache_t *mc, apr_memcache_server_t *ms)
{
    apr_status_t rv = APR_SUCCESS;

    if (ms->status == APR_MC_SERVER_LIVE) {
        return rv;
    }

    rv = make_server_live(mc, ms);
    return rv;
}

APU_DECLARE(apr_status_t) apr_memcache_disable_server(apr_memcache_t *mc, apr_memcache_server_t *ms)
{
    return make_server_dead(mc, ms);
}

static apr_status_t conn_connect(apr_memcache_conn_t *conn)
{
    apr_status_t rv = APR_SUCCESS;
    apr_sockaddr_t *sa;

    rv = apr_sockaddr_info_get(&sa, conn->ms->host, APR_INET, conn->ms->port, 0, conn->p);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = apr_socket_timeout_set(conn->sock, 1 * APR_USEC_PER_SEC);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = apr_socket_connect(conn->sock, sa);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = apr_socket_timeout_set(conn->sock, -1);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    return rv;
}


static apr_status_t
mc_conn_construct(void **conn_, void *params, apr_pool_t *pool)
{
    apr_status_t rv = APR_SUCCESS;
    apr_memcache_conn_t *conn;
    apr_pool_t *np;
    apr_pool_t *tp;
    apr_memcache_server_t *ms = params;

    rv = apr_pool_create(&np, pool);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = apr_pool_create(&tp, np);
    if (rv != APR_SUCCESS) {
        apr_pool_destroy(np);
        return rv;
    }

    conn = apr_palloc(np, sizeof( apr_memcache_conn_t ));

    conn->p = np;
    conn->tp = tp;

    rv = apr_socket_create(&conn->sock, APR_INET, SOCK_STREAM, 0, np);

    if (rv != APR_SUCCESS) {
        apr_pool_destroy(np);
        return rv;
    }

    conn->buffer = apr_palloc(conn->p, BUFFER_SIZE);
    conn->blen = 0;
    conn->ms = ms;

    rv = conn_connect(conn);
    if (rv != APR_SUCCESS) {
        apr_pool_destroy(np);
    }
    else {
        *conn_ = conn;
    }
    
    return rv;
}

#if APR_HAS_THREADS
static apr_status_t
mc_conn_destruct(void *conn_, void *params, apr_pool_t *pool)
{
    apr_memcache_conn_t *conn = (apr_memcache_conn_t*)conn_;
    struct iovec vec[2];
    apr_size_t written;
    
    /* send a quit message to the memcached server to be nice about it. */
    vec[0].iov_base = MC_QUIT;
    vec[0].iov_len = MC_QUIT_LEN;

    vec[1].iov_base = MC_EOL;
    vec[1].iov_len = MC_EOL_LEN;
    
    /* Return values not checked, since we just want to make it go away. */
    apr_socket_sendv(conn->sock, vec, 2, &written);
    apr_socket_close(conn->sock);

    apr_pool_destroy(conn->p);
    
    return APR_SUCCESS;
}
#endif

APU_DECLARE(apr_status_t) apr_memcache_server_create(apr_pool_t *p, 
                                                     const char *host, apr_port_t port, 
                                                     apr_uint32_t min, apr_uint32_t smax,
                                                     apr_uint32_t max, apr_uint32_t ttl,
                                                     apr_memcache_server_t **ms)
{
    apr_status_t rv = APR_SUCCESS;
    apr_memcache_server_t *server;
    apr_pool_t *np;

    rv = apr_pool_create(&np, p);

    server = apr_palloc(np, sizeof(apr_memcache_server_t));

    server->p = np;
    server->host = apr_pstrdup(np, host);
    server->port = port;
    server->status = APR_MC_SERVER_DEAD;
#if APR_HAS_THREADS
    rv = apr_thread_mutex_create(&server->lock, APR_THREAD_MUTEX_DEFAULT, np);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = apr_reslist_create(&server->conns, 
                               min,                     /* hard minimum */
                               smax,                    /* soft maximum */
                               max,                     /* hard maximum */
                               ttl,                     /* Time to live */
                               mc_conn_construct,       /* Make a New Connection */
                               mc_conn_destruct,        /* Kill Old Connection */
                               server, np);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    apr_reslist_cleanup_order_set(server->conns, APR_RESLIST_CLEANUP_FIRST);
#else
    rv = mc_conn_construct((void**)&(server->conn), server, np);
    if (rv != APR_SUCCESS) {
        return rv;
    }
#endif

    *ms = server;

    return rv;
}

APU_DECLARE(apr_status_t) apr_memcache_create(apr_pool_t *p,
                                              apr_uint16_t max_servers, apr_uint32_t flags,
                                              apr_memcache_t **memcache) 
{
    apr_status_t rv = APR_SUCCESS;
    apr_memcache_t *mc;
    
    mc = apr_palloc(p, sizeof(apr_memcache_t));
    mc->p = p;
    mc->nalloc = max_servers;
    mc->ntotal = 0;
    mc->live_servers = apr_palloc(p, mc->nalloc * sizeof(struct apr_memcache_server_t *));
    mc->hash_func = NULL;
    mc->hash_baton = NULL;
    mc->server_func = NULL;
    mc->server_baton = NULL;
    *memcache = mc;
    return rv;
}


/* The crc32 functions and data was originally written by Spencer
 * Garrett <srg@quick.com> and was gleaned from the PostgreSQL source
 * tree via the files contrib/ltree/crc32.[ch] and from FreeBSD at
 * src/usr.bin/cksum/crc32.c.
 */ 

static const apr_uint32_t crc32tab[256] = {
  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
  0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
  0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
  0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
  0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
  0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
  0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
  0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
  0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
  0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
  0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
  0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
  0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
  0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
  0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
  0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
  0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
  0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
  0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
  0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
  0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
  0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
  0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
  0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
  0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
  0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
  0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
  0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
  0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
  0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
  0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
  0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
  0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
  0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
  0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
  0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
  0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
  0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
  0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
  0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
  0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
  0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
  0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
  0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
  0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
  0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
  0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
  0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
  0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
  0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
  0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
  0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
  0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
  0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
  0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
  0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
  0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
  0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
  0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
  0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
};

APU_DECLARE(apr_uint32_t) apr_memcache_hash_crc32(void *baton, 
                                                  const char *data,
                                                  const apr_size_t data_len)
{
    apr_uint32_t i;
    apr_uint32_t crc;
    crc = ~0;
    
    for (i = 0; i < data_len; i++)
        crc = (crc >> 8) ^ crc32tab[(crc ^ (data[i])) & 0xff];
    
    return ~crc;
}

APU_DECLARE(apr_uint32_t) apr_memcache_hash_default(void *baton, 
                                                    const char *data,
                                                    const apr_size_t data_len)
{
    /* The default Perl Client doesn't actually use just crc32 -- it shifts it again
     * like this....
     */
    return ((apr_memcache_hash_crc32(baton, data, data_len) >> 16) & 0x7fff);
}

APU_DECLARE(apr_uint32_t) apr_memcache_hash(apr_memcache_t *mc,
                                            const char *data,
                                            const apr_size_t data_len)
{
    if (mc->hash_func) {
        return mc->hash_func(mc->hash_baton, data, data_len);
    }
    else {
        return apr_memcache_hash_default(NULL, data, data_len);
    }
}

static apr_status_t get_server_line(apr_memcache_conn_t *conn)
{
    apr_size_t bsize = BUFFER_SIZE;
    apr_status_t rv = APR_SUCCESS;

    rv = apr_brigade_split_line(conn->tb, conn->bb, APR_BLOCK_READ, BUFFER_SIZE);

    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = apr_brigade_flatten(conn->tb, conn->buffer, &bsize);

    if (rv != APR_SUCCESS) {
        return rv;
    }

    conn->blen = bsize;
    conn->buffer[bsize] = '\0';

    return apr_brigade_cleanup(conn->tb);
}

static apr_status_t storage_cmd_write(apr_memcache_t *mc,
                                      char *cmd,
                                      const apr_size_t cmd_size,
                                      const char *key,
                                      char *data,
                                      const apr_size_t data_size,
                                      apr_uint32_t timeout,
                                      apr_uint16_t flags)
{
    apr_uint32_t hash;
    apr_memcache_server_t *ms;
    apr_memcache_conn_t *conn;
    apr_status_t rv;
    apr_size_t written;
    struct iovec vec[5];
    apr_size_t klen;

    apr_size_t key_size = strlen(key);

    hash = apr_memcache_hash(mc, key, key_size);

    ms = apr_memcache_find_server_hash(mc, hash);

    if (ms == NULL)
        return APR_NOTFOUND;

    rv = ms_find_conn(ms, &conn);

    if (rv != APR_SUCCESS) {
        apr_memcache_disable_server(mc, ms);
        return rv;
    }

    /* <command name> <key> <flags> <exptime> <bytes>\r\n<data>\r\n */

    vec[0].iov_base = cmd;
    vec[0].iov_len  = cmd_size;

    vec[1].iov_base = (void*)key;
    vec[1].iov_len  = key_size;

    klen = apr_snprintf(conn->buffer, BUFFER_SIZE, " %u %u %" APR_SIZE_T_FMT " " MC_EOL,
                        flags, timeout, data_size);

    vec[2].iov_base = conn->buffer;
    vec[2].iov_len  = klen;

    vec[3].iov_base = data;
    vec[3].iov_len  = data_size;

    vec[4].iov_base = MC_EOL;
    vec[4].iov_len  = MC_EOL_LEN;

    rv = apr_socket_sendv(conn->sock, vec, 5, &written);

    if (rv != APR_SUCCESS) {
        ms_bad_conn(ms, conn);
        apr_memcache_disable_server(mc, ms);
        return rv;
    }

    rv = get_server_line(conn);

    if (rv != APR_SUCCESS) {
        ms_bad_conn(ms, conn);
        apr_memcache_disable_server(mc, ms);
        return rv;
    }

    if (strcmp(conn->buffer, MS_STORED MC_EOL) == 0) {
        rv = APR_SUCCESS;
    }
    else if (strcmp(conn->buffer, MS_NOT_STORED MC_EOL) == 0) {
        rv = APR_EEXIST;
    }
    else {
        rv = APR_EGENERAL;
    }

    ms_release_conn(ms, conn);

    return rv;
}

APU_DECLARE(apr_status_t)
apr_memcache_set(apr_memcache_t *mc,
                 const char *key,
                 char *data,
                 const apr_size_t data_size,
                 apr_uint32_t timeout,
                 apr_uint16_t flags)
{
    return storage_cmd_write(mc,
                           MC_SET, MC_SET_LEN,
                           key,
                           data, data_size,
                           timeout, flags);
}

APU_DECLARE(apr_status_t)
apr_memcache_add(apr_memcache_t *mc,
                 const char *key,
                 char *data,
                 const apr_size_t data_size,
                 apr_uint32_t timeout,
                 apr_uint16_t flags)
{
    return storage_cmd_write(mc, 
                           MC_ADD, MC_ADD_LEN,
                           key,
                           data, data_size,
                           timeout, flags);
}

APU_DECLARE(apr_status_t)
apr_memcache_replace(apr_memcache_t *mc,
                 const char *key,
                 char *data,
                 const apr_size_t data_size,
                 apr_uint32_t timeout,
                 apr_uint16_t flags)
{
    return storage_cmd_write(mc,
                           MC_REPLACE, MC_REPLACE_LEN,
                           key,
                           data, data_size,
                           timeout, flags);

}

APU_DECLARE(apr_status_t)
apr_memcache_getp(apr_memcache_t *mc,
                  apr_pool_t *p,
                  const char *key,
                  char **baton,
                  apr_size_t *new_length,
                  apr_uint16_t *flags_)
{
    apr_status_t rv;
    apr_memcache_server_t *ms;
    apr_memcache_conn_t *conn;
    apr_uint32_t hash;
    apr_size_t written;
    apr_size_t klen = strlen(key);
    struct iovec vec[3];

    hash = apr_memcache_hash(mc, key, klen);
    ms = apr_memcache_find_server_hash(mc, hash);
    if (ms == NULL)
        return APR_NOTFOUND;
    
    rv = ms_find_conn(ms, &conn);

    if (rv != APR_SUCCESS) {
        apr_memcache_disable_server(mc, ms);
        return rv;
    }

    /* get <key>[ <key>[...]]\r\n */
    vec[0].iov_base = MC_GET;
    vec[0].iov_len  = MC_GET_LEN;

    vec[1].iov_base = (void*)key;
    vec[1].iov_len  = klen;

    vec[2].iov_base = MC_EOL;
    vec[2].iov_len  = MC_EOL_LEN;

    rv = apr_socket_sendv(conn->sock, vec, 3, &written);

    if (rv != APR_SUCCESS) {
        ms_bad_conn(ms, conn);
        apr_memcache_disable_server(mc, ms);
        return rv;
    }

    rv = get_server_line(conn);
    if (rv != APR_SUCCESS) {
        ms_bad_conn(ms, conn);
        apr_memcache_disable_server(mc, ms);
        return rv;
    }

    if (strncmp(MS_VALUE, conn->buffer, MS_VALUE_LEN) == 0) {
        char *flags;
        char *length;
        char *last;
        apr_size_t len = 0;

        flags = apr_strtok(conn->buffer, " ", &last);
        flags = apr_strtok(NULL, " ", &last);
        flags = apr_strtok(NULL, " ", &last);

        if (flags_) {
            *flags_ = atoi(flags);
        }

        length = apr_strtok(NULL, " ", &last);
        if (length) {
            len = atoi(length);
        }

        if (len < 0)  {
            *new_length = 0;
            *baton = NULL;
        }
        else {
            apr_bucket_brigade *bbb;
            apr_bucket *e;

            /* eat the trailing \r\n */
            rv = apr_brigade_partition(conn->bb, len+2, &e);

            if (rv != APR_SUCCESS) {
                ms_bad_conn(ms, conn);
                apr_memcache_disable_server(mc, ms);
                return rv;
            }
            
            bbb = apr_brigade_split(conn->bb, e);

            rv = apr_brigade_pflatten(conn->bb, baton, &len, p);

            if (rv != APR_SUCCESS) {
                ms_bad_conn(ms, conn);
                apr_memcache_disable_server(mc, ms);
                return rv;
            }

            rv = apr_brigade_destroy(conn->bb);
            if (rv != APR_SUCCESS) {
                ms_bad_conn(ms, conn);
                apr_memcache_disable_server(mc, ms);
                return rv;
            }

            conn->bb = bbb;

            *new_length = len - 2;
            (*baton)[*new_length] = '\0';
        }
        
        rv = get_server_line(conn);
        if (rv != APR_SUCCESS) {
            ms_bad_conn(ms, conn);
            apr_memcache_disable_server(mc, ms);
            return rv;
        }

        if (strncmp(MS_END, conn->buffer, MS_END_LEN) != 0) {
            rv = APR_EGENERAL;
        }
    }
    else if (strncmp(MS_END, conn->buffer, MS_END_LEN) == 0) {
        rv = APR_NOTFOUND;
    }
    else {
        rv = APR_EGENERAL;
    }

    ms_release_conn(ms, conn);

    return rv;
}

APU_DECLARE(apr_status_t)
apr_memcache_delete(apr_memcache_t *mc,
                    const char *key,
                    apr_uint32_t timeout)
{
    apr_status_t rv;
    apr_memcache_server_t *ms;
    apr_memcache_conn_t *conn;
    apr_uint32_t hash;
    apr_size_t written;
    struct iovec vec[3];
    apr_size_t klen = strlen(key);

    hash = apr_memcache_hash(mc, key, klen);
    ms = apr_memcache_find_server_hash(mc, hash);
    if (ms == NULL)
        return APR_NOTFOUND;
    
    rv = ms_find_conn(ms, &conn);

    if (rv != APR_SUCCESS) {
        apr_memcache_disable_server(mc, ms);
        return rv;
    }

    /* delete <key> <time>\r\n */
    vec[0].iov_base = MC_DELETE;
    vec[0].iov_len  = MC_DELETE_LEN;

    vec[1].iov_base = (void*)key;
    vec[1].iov_len  = klen;

    klen = apr_snprintf(conn->buffer, BUFFER_SIZE, " %u" MC_EOL, timeout);

    vec[2].iov_base = conn->buffer;
    vec[2].iov_len  = klen;

    rv = apr_socket_sendv(conn->sock, vec, 3, &written);

    if (rv != APR_SUCCESS) {
        ms_bad_conn(ms, conn);
        apr_memcache_disable_server(mc, ms);
        return rv;
    }

    rv = get_server_line(conn);
    if (rv != APR_SUCCESS) {
        ms_bad_conn(ms, conn);
        apr_memcache_disable_server(mc, ms);
        return rv;
    }

    if (strncmp(MS_DELETED, conn->buffer, MS_DELETED_LEN) == 0) {
        rv = APR_SUCCESS;
    }
    else if (strncmp(MS_NOT_FOUND, conn->buffer, MS_NOT_FOUND_LEN) == 0) {
        rv = APR_NOTFOUND;
    }
    else {
        rv = APR_EGENERAL;
    }

    ms_release_conn(ms, conn);

    return rv;
}

static apr_status_t num_cmd_write(apr_memcache_t *mc,
                                      char *cmd,
                                      const apr_uint32_t cmd_size,
                                      const char *key,
                                      const apr_int32_t inc,
                                      apr_uint32_t *new_value)
{
    apr_status_t rv;
    apr_memcache_server_t *ms;
    apr_memcache_conn_t *conn;
    apr_uint32_t hash;
    apr_size_t written;
    struct iovec vec[3];
    apr_size_t klen = strlen(key);

    hash = apr_memcache_hash(mc, key, klen);
    ms = apr_memcache_find_server_hash(mc, hash);
    if (ms == NULL)
        return APR_NOTFOUND;
    
    rv = ms_find_conn(ms, &conn);

    if (rv != APR_SUCCESS) {
        apr_memcache_disable_server(mc, ms);
        return rv;
    }

    /* <cmd> <key> <value>\r\n */
    vec[0].iov_base = cmd;
    vec[0].iov_len  = cmd_size;

    vec[1].iov_base = (void*)key;
    vec[1].iov_len  = klen;

    klen = apr_snprintf(conn->buffer, BUFFER_SIZE, " %u" MC_EOL, inc);

    vec[2].iov_base = conn->buffer;
    vec[2].iov_len  = klen;

    rv = apr_socket_sendv(conn->sock, vec, 3, &written);

    if (rv != APR_SUCCESS) {
        ms_bad_conn(ms, conn);
        apr_memcache_disable_server(mc, ms);
        return rv;
    }

    rv = get_server_line(conn);
    if (rv != APR_SUCCESS) {
        ms_bad_conn(ms, conn);
        apr_memcache_disable_server(mc, ms);
        return rv;
    }

    if (strncmp(MS_ERROR, conn->buffer, MS_ERROR_LEN) == 0) {
        rv = APR_EGENERAL;
    }
    else if (strncmp(MS_NOT_FOUND, conn->buffer, MS_NOT_FOUND_LEN) == 0) {
        rv = APR_NOTFOUND;
    }
    else {
        if (new_value) {
            *new_value = atoi(conn->buffer);
        }
        rv = APR_SUCCESS;
    }

    ms_release_conn(ms, conn);

    return rv;
}

APU_DECLARE(apr_status_t)
apr_memcache_incr(apr_memcache_t *mc,
                    const char *key,
                    apr_int32_t inc,
                    apr_uint32_t *new_value)
{
    return num_cmd_write(mc,
                         MC_INCR,
                         MC_INCR_LEN,
                         key,
                         inc, 
                         new_value);
}


APU_DECLARE(apr_status_t)
apr_memcache_decr(apr_memcache_t *mc,
                    const char *key,
                    apr_int32_t inc,
                    apr_uint32_t *new_value)
{
    return num_cmd_write(mc,
                         MC_DECR,
                         MC_DECR_LEN,
                         key,
                         inc, 
                         new_value);
}



APU_DECLARE(apr_status_t)
apr_memcache_version(apr_memcache_server_t *ms,
                  apr_pool_t *p,
                  char **baton)
{
    apr_status_t rv;
    apr_memcache_conn_t *conn;
    apr_size_t written;
    struct iovec vec[2];

    rv = ms_find_conn(ms, &conn);

    if (rv != APR_SUCCESS) {
        return rv;
    }

    /* version\r\n */
    vec[0].iov_base = MC_VERSION;
    vec[0].iov_len  = MC_VERSION_LEN;

    vec[1].iov_base = MC_EOL;
    vec[1].iov_len  = MC_EOL_LEN;

    rv = apr_socket_sendv(conn->sock, vec, 2, &written);

    if (rv != APR_SUCCESS) {
        ms_bad_conn(ms, conn);
        return rv;
    }

    rv = get_server_line(conn);
    if (rv != APR_SUCCESS) {
        ms_bad_conn(ms, conn);
        return rv;
    }

    if (strncmp(MS_VERSION, conn->buffer, MS_VERSION_LEN) == 0) {
        *baton = apr_pstrmemdup(p, conn->buffer+MS_VERSION_LEN+1, 
                                conn->blen - MS_VERSION_LEN - 2);
        rv = APR_SUCCESS;
    }
    else {
        rv = APR_EGENERAL;
    }

    ms_release_conn(ms, conn);

    return rv;
}

apr_status_t mc_version_ping(apr_memcache_server_t *ms)
{
    apr_status_t rv;
    apr_size_t written;
    struct iovec vec[2];
    apr_memcache_conn_t *conn;

    rv = ms_find_conn(ms, &conn);

    if (rv != APR_SUCCESS) {
        return rv;
    }

    /* version\r\n */
    vec[0].iov_base = MC_VERSION;
    vec[0].iov_len  = MC_VERSION_LEN;

    vec[1].iov_base = MC_EOL;
    vec[1].iov_len  = MC_EOL_LEN;

    rv = apr_socket_sendv(conn->sock, vec, 2, &written);

    if (rv != APR_SUCCESS) {
        ms_bad_conn(ms, conn);
        return rv;
    }

    rv = get_server_line(conn);
    ms_release_conn(ms, conn);
    return rv;
}


APU_DECLARE(void) 
apr_memcache_add_multget_key(apr_pool_t *data_pool,
                             const char* key,
                             apr_hash_t **values)
{
    apr_memcache_value_t* value;
    apr_size_t klen = strlen(key);

    /* create the value hash if need be */
    if (!*values) {
        *values = apr_hash_make(data_pool);
    }

    /* init key and add it to the value hash */
    value = apr_pcalloc(data_pool, sizeof(apr_memcache_value_t));

    value->status = APR_NOTFOUND;
    value->key = apr_pstrdup(data_pool, key);

    apr_hash_set(*values, value->key, klen, value);
}

static void mget_conn_result(int serverup,
                             int connup,
                             apr_status_t rv,
                             apr_memcache_t *mc,
                             apr_memcache_server_t *ms,
                             apr_memcache_conn_t *conn,
                             struct cache_server_query_t *server_query,
                             apr_hash_t *values,
                             apr_hash_t *server_queries)
{
    apr_int32_t j;
    apr_memcache_value_t* value;
    
    apr_hash_set(server_queries, &ms, sizeof(ms), NULL);

    if (connup) {
        ms_release_conn(ms, conn);
    } else {
        ms_bad_conn(ms, conn);

        if (!serverup) {
            apr_memcache_disable_server(mc, ms);
        }
    }
    
    for (j = 1; j < server_query->query_vec_count ; j+=2) {
        if (server_query->query_vec[j].iov_base) {
            value = apr_hash_get(values, server_query->query_vec[j].iov_base,
                                 strlen(server_query->query_vec[j].iov_base));
            
            if (value->status == APR_NOTFOUND) {
                value->status = rv;
            }
        }
    }
}

APU_DECLARE(apr_status_t)
apr_memcache_multgetp(apr_memcache_t *mc,
                      apr_pool_t *temp_pool,
                      apr_pool_t *data_pool,
                      apr_hash_t *values)
{
    apr_status_t rv;
    apr_memcache_server_t* ms;
    apr_memcache_conn_t* conn;
    apr_uint32_t hash;
    apr_size_t written;
    apr_size_t klen;

    apr_memcache_value_t* value;
    apr_hash_index_t* value_hash_index;

    /* this is a little over aggresive, but beats multiple loops
     * to figure out how long each vector needs to be per-server.
     */
    apr_int32_t veclen = 2 + 2 * apr_hash_count(values) - 1; /* get <key>[<space><key>...]\r\n */
    apr_int32_t i, j;
    apr_int32_t queries_sent;
    apr_int32_t queries_recvd;

    apr_hash_t * server_queries = apr_hash_make(temp_pool);
    struct cache_server_query_t* server_query;
    apr_hash_index_t * query_hash_index;

    apr_pollset_t* pollset;
    const apr_pollfd_t* activefds;
    apr_pollfd_t* pollfds;


    /* build all the queries */
    value_hash_index = apr_hash_first(temp_pool, values);
    while (value_hash_index) {
        void *v;
        apr_hash_this(value_hash_index, NULL, NULL, &v);
        value = v;
        value_hash_index = apr_hash_next(value_hash_index);
        klen = strlen(value->key);

        hash = apr_memcache_hash(mc, value->key, klen);
        ms = apr_memcache_find_server_hash(mc, hash);
        if (ms == NULL) {
            continue;
        }

        server_query = apr_hash_get(server_queries, &ms, sizeof(ms));

        if (!server_query) {
            rv = ms_find_conn(ms, &conn);

            if (rv != APR_SUCCESS) {
                apr_memcache_disable_server(mc, ms);
                value->status = rv;
                continue;
            }

            server_query = apr_pcalloc(temp_pool,sizeof(struct cache_server_query_t));

            apr_hash_set(server_queries, &ms, sizeof(ms), server_query);

            server_query->ms = ms;
            server_query->conn = conn;
            server_query->query_vec = apr_pcalloc(temp_pool, sizeof(struct iovec)*veclen);

            /* set up the first key */
            server_query->query_vec[0].iov_base = MC_GET;
            server_query->query_vec[0].iov_len  = MC_GET_LEN;

            server_query->query_vec[1].iov_base = (void*)(value->key);
            server_query->query_vec[1].iov_len  = klen;

            server_query->query_vec[2].iov_base = MC_EOL;
            server_query->query_vec[2].iov_len  = MC_EOL_LEN;

            server_query->query_vec_count = 3;
        }
        else {
            j = server_query->query_vec_count - 1;

            server_query->query_vec[j].iov_base = MC_WS;
            server_query->query_vec[j].iov_len  = MC_WS_LEN;
            j++;

            server_query->query_vec[j].iov_base = (void*)(value->key);
            server_query->query_vec[j].iov_len  = klen;
            j++;

            server_query->query_vec[j].iov_base = MC_EOL;
            server_query->query_vec[j].iov_len  = MC_EOL_LEN;
            j++;

           server_query->query_vec_count = j;
        }
    }

    /* create polling structures */
    pollfds = apr_pcalloc(temp_pool, apr_hash_count(server_queries) * sizeof(apr_pollfd_t));
    
    rv = apr_pollset_create(&pollset, apr_hash_count(server_queries), temp_pool, 0);

    if (rv != APR_SUCCESS) {
        query_hash_index = apr_hash_first(temp_pool, server_queries);

        while (query_hash_index) {
            void *v;
            apr_hash_this(query_hash_index, NULL, NULL, &v);
            server_query = v;
            query_hash_index = apr_hash_next(query_hash_index);

            mget_conn_result(TRUE, TRUE, rv, mc, server_query->ms, server_query->conn,
                             server_query, values, server_queries);
        }

        return rv;
    }

    /* send all the queries */
    queries_sent = 0;
    query_hash_index = apr_hash_first(temp_pool, server_queries);

    while (query_hash_index) {
        void *v;
        apr_hash_this(query_hash_index, NULL, NULL, &v);
        server_query = v;
        query_hash_index = apr_hash_next(query_hash_index);

        conn = server_query->conn;
        ms = server_query->ms;

        for (i = 0, rv = APR_SUCCESS; i < veclen && rv == APR_SUCCESS; i += APR_MAX_IOVEC_SIZE) {
            rv = apr_socket_sendv(conn->sock, &(server_query->query_vec[i]),
                                  veclen-i>APR_MAX_IOVEC_SIZE ? APR_MAX_IOVEC_SIZE : veclen-i , &written);
        }

        if (rv != APR_SUCCESS) {
            mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
                             server_query, values, server_queries);
            continue;
        }

        pollfds[queries_sent].desc_type = APR_POLL_SOCKET;
        pollfds[queries_sent].reqevents = APR_POLLIN;
        pollfds[queries_sent].p = temp_pool;
        pollfds[queries_sent].desc.s = conn->sock;
        pollfds[queries_sent].client_data = (void *)server_query;
        apr_pollset_add (pollset, &pollfds[queries_sent]);

        queries_sent++;
    }

    while (queries_sent) {
        rv = apr_pollset_poll(pollset, MULT_GET_TIMEOUT, &queries_recvd, &activefds);

        if (rv != APR_SUCCESS) {
            /* timeout */
            queries_sent = 0;
            continue;
        }
        for (i = 0; i < queries_recvd; i++) {
            server_query = activefds[i].client_data;
            conn = server_query->conn;
            ms = server_query->ms;

           rv = get_server_line(conn);

           if (rv != APR_SUCCESS) {
               apr_pollset_remove (pollset, &activefds[i]);
               mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
                                server_query, values, server_queries);
               queries_sent--;
               continue;
           }

           if (strncmp(MS_VALUE, conn->buffer, MS_VALUE_LEN) == 0) {
               char *key;
               char *flags;
               char *length;
               char *last;
               char *data;
               apr_size_t len = 0;

               key = apr_strtok(conn->buffer, " ", &last); /* just the VALUE, ignore */
               key = apr_strtok(NULL, " ", &last);
               flags = apr_strtok(NULL, " ", &last);


               length = apr_strtok(NULL, " ", &last);
               if (length) {
                   len = atoi(length);
               }

               value = apr_hash_get(values, key, strlen(key));

               
               if (value) {
                   if (len >= 0)  {
                       apr_bucket_brigade *bbb;
                       apr_bucket *e;
                       
                       /* eat the trailing \r\n */
                       rv = apr_brigade_partition(conn->bb, len+2, &e);
                       
                       if (rv != APR_SUCCESS) {
                           apr_pollset_remove (pollset, &activefds[i]);
                           mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
                                            server_query, values, server_queries);
                           queries_sent--;
                           continue;
                       }
                       
                       bbb = apr_brigade_split(conn->bb, e);
                       
                       rv = apr_brigade_pflatten(conn->bb, &data, &len, data_pool);
                       
                       if (rv != APR_SUCCESS) {
                           apr_pollset_remove (pollset, &activefds[i]);
                           mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
                                            server_query, values, server_queries);
                           queries_sent--;
                           continue;
                       }
                       
                       rv = apr_brigade_destroy(conn->bb);
                       if (rv != APR_SUCCESS) {
                           apr_pollset_remove (pollset, &activefds[i]);
                           mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
                                            server_query, values, server_queries);
                           queries_sent--;
                           continue;
                       }
                       
                       conn->bb = bbb;
                       
                       value->len = len - 2;
                       data[value->len] = '\0';
                       value->data = data;
                   }
                   
                   value->status = rv;
                   value->flags = atoi(flags);
                   
                   /* stay on the server */
                   i--;
                   
               }
               else {
                   /* TODO: Server Sent back a key I didn't ask for or my
                    *       hash is corrupt */
               }
           }
           else if (strncmp(MS_END, conn->buffer, MS_END_LEN) == 0) {
               /* this connection is done */
               apr_pollset_remove (pollset, &activefds[i]);
               ms_release_conn(ms, conn);
               apr_hash_set(server_queries, &ms, sizeof(ms), NULL);
               
               queries_sent--;
           }
           else {
               /* unknown reply? */
               rv = APR_EGENERAL;
           }
           
        } /* /for */
    } /* /while */
    
    query_hash_index = apr_hash_first(temp_pool, server_queries);
    while (query_hash_index) {
        void *v;
        apr_hash_this(query_hash_index, NULL, NULL, &v);
        server_query = v;
        query_hash_index = apr_hash_next(query_hash_index);
        
        conn = server_query->conn;
        ms = server_query->ms;
        
        mget_conn_result(TRUE, (rv == APR_SUCCESS), rv, mc, ms, conn,
                         server_query, values, server_queries);
        continue;
    }
    
    apr_pollset_destroy(pollset);
    apr_pool_clear(temp_pool);
    return APR_SUCCESS;
    
}



/**
 * Define all of the strings for stats
 */

#define STAT_pid MS_STAT " pid "
#define STAT_pid_LEN (sizeof(STAT_pid)-1)

#define STAT_uptime MS_STAT " uptime "
#define STAT_uptime_LEN (sizeof(STAT_uptime)-1)

#define STAT_time MS_STAT " time "
#define STAT_time_LEN (sizeof(STAT_time)-1)

#define STAT_version MS_STAT " version "
#define STAT_version_LEN (sizeof(STAT_version)-1)

#define STAT_pointer_size MS_STAT " pointer_size "
#define STAT_pointer_size_LEN (sizeof(STAT_pointer_size)-1)

#define STAT_rusage_user MS_STAT " rusage_user "
#define STAT_rusage_user_LEN (sizeof(STAT_rusage_user)-1)

#define STAT_rusage_system MS_STAT " rusage_system "
#define STAT_rusage_system_LEN (sizeof(STAT_rusage_system)-1)

#define STAT_curr_items MS_STAT " curr_items "
#define STAT_curr_items_LEN (sizeof(STAT_curr_items)-1)

#define STAT_total_items MS_STAT " total_items "
#define STAT_total_items_LEN (sizeof(STAT_total_items)-1)

#define STAT_bytes MS_STAT " bytes "
#define STAT_bytes_LEN (sizeof(STAT_bytes)-1)

#define STAT_curr_connections MS_STAT " curr_connections "
#define STAT_curr_connections_LEN (sizeof(STAT_curr_connections)-1)

#define STAT_total_connections MS_STAT " total_connections "
#define STAT_total_connections_LEN (sizeof(STAT_total_connections)-1)

#define STAT_connection_structures MS_STAT " connection_structures "
#define STAT_connection_structures_LEN (sizeof(STAT_connection_structures)-1)

#define STAT_cmd_get MS_STAT " cmd_get "
#define STAT_cmd_get_LEN (sizeof(STAT_cmd_get)-1)

#define STAT_cmd_set MS_STAT " cmd_set "
#define STAT_cmd_set_LEN (sizeof(STAT_cmd_set)-1)

#define STAT_get_hits MS_STAT " get_hits "
#define STAT_get_hits_LEN (sizeof(STAT_get_hits)-1)

#define STAT_get_misses MS_STAT " get_misses "
#define STAT_get_misses_LEN (sizeof(STAT_get_misses)-1)

#define STAT_evictions MS_STAT " evictions "
#define STAT_evictions_LEN (sizeof(STAT_evictions)-1)

#define STAT_bytes_read MS_STAT " bytes_read "
#define STAT_bytes_read_LEN (sizeof(STAT_bytes_read)-1)

#define STAT_bytes_written MS_STAT " bytes_written "
#define STAT_bytes_written_LEN (sizeof(STAT_bytes_written)-1)

#define STAT_limit_maxbytes MS_STAT " limit_maxbytes "
#define STAT_limit_maxbytes_LEN (sizeof(STAT_limit_maxbytes)-1)

#define STAT_threads MS_STAT " threads "
#define STAT_threads_LEN (sizeof(STAT_threads)-1)

static const char *stat_read_string(apr_pool_t *p, char *buf, apr_size_t len)
{
    /* remove trailing \r\n and null char */
    return apr_pstrmemdup(p, buf, len-2);
}

static apr_uint32_t stat_read_uint32(apr_pool_t *p, char *buf, apr_size_t  len)
{
    buf[len-2] = '\0';
    return atoi(buf);
}

static apr_uint64_t stat_read_uint64(apr_pool_t *p, char *buf, apr_size_t  len)
{
    buf[len-2] = '\0';
    return apr_atoi64(buf);
}

static apr_time_t stat_read_time(apr_pool_t *p, char *buf, apr_size_t  len)
{
    buf[len-2] = '\0';
    return apr_time_from_sec(atoi(buf));
}

static apr_time_t stat_read_rtime(apr_pool_t *p, char *buf, apr_size_t  len)
{
    char *tok;
    char *secs;
    char *usecs;
    const char *sep = ":.";

    buf[len-2] = '\0';

    secs = apr_strtok(buf, sep, &tok);
    usecs = apr_strtok(NULL, sep, &tok);
    if (secs && usecs) {
        return apr_time_make(atoi(secs), atoi(usecs));
    }
    else {
        return apr_time_make(0, 0);
    }
}

/**
 * I got tired of Typing. Meh. 
 *
 * TODO: Convert it to static tables to make it cooler.
 */

#define mc_stat_cmp(name) \
    strncmp(STAT_ ## name, conn->buffer, STAT_ ## name ## _LEN) == 0

#define mc_stat_str(name) \
    stat_read_string(p, conn->buffer + name, \
                     conn->blen - name)

#define mc_stat_uint32(name) \
    stat_read_uint32(p, conn->buffer + name, \
                     conn->blen - name)

#define mc_stat_uint64(name) \
    stat_read_uint64(p, conn->buffer + name, \
                     conn->blen - name)

#define mc_stat_time(name) \
    stat_read_time(p, conn->buffer + name, \
                     conn->blen - name)

#define mc_stat_rtime(name) \
    stat_read_rtime(p, conn->buffer + name, \
                     conn->blen - name)


#define mc_do_stat(name, type) \
    if (mc_stat_cmp(name)) { \
        stats-> name = mc_stat_ ## type ((STAT_ ## name ## _LEN)); \
    } 

static void update_stats(apr_pool_t *p, apr_memcache_conn_t *conn, 
                         apr_memcache_stats_t *stats)
{

    mc_do_stat(version, str)
    else mc_do_stat(pid, uint32)
    else mc_do_stat(uptime, uint32)
    else mc_do_stat(pointer_size, uint32)
    else mc_do_stat(time, time)
    else mc_do_stat(rusage_user, rtime)
    else mc_do_stat(rusage_system, rtime)
    else mc_do_stat(curr_items, uint32)
    else mc_do_stat(total_items, uint32)
    else mc_do_stat(bytes, uint64)
    else mc_do_stat(curr_connections, uint32)
    else mc_do_stat(total_connections, uint32)
    else mc_do_stat(connection_structures, uint32)
    else mc_do_stat(cmd_get, uint32)
    else mc_do_stat(cmd_set, uint32)
    else mc_do_stat(get_hits, uint32)
    else mc_do_stat(get_misses, uint32)
    else mc_do_stat(evictions, uint64)
    else mc_do_stat(bytes_read, uint64)
    else mc_do_stat(bytes_written, uint64)
    else mc_do_stat(limit_maxbytes, uint32)
    else mc_do_stat(threads, uint32)
}

APU_DECLARE(apr_status_t)
apr_memcache_stats(apr_memcache_server_t *ms,
                  apr_pool_t *p,
                  apr_memcache_stats_t **stats) 
{
    apr_memcache_stats_t *ret;
    apr_status_t rv;
    apr_memcache_conn_t *conn;
    apr_size_t written;
    struct iovec vec[2];

    rv = ms_find_conn(ms, &conn);

    if (rv != APR_SUCCESS) {
        return rv;
    }

    /* version\r\n */
    vec[0].iov_base = MC_STATS;
    vec[0].iov_len  = MC_STATS_LEN;

    vec[1].iov_base = MC_EOL;
    vec[1].iov_len  = MC_EOL_LEN;

    rv = apr_socket_sendv(conn->sock, vec, 2, &written);

    if (rv != APR_SUCCESS) {
        ms_bad_conn(ms, conn);
        return rv;
    }

    ret = apr_pcalloc(p, sizeof(apr_memcache_stats_t));

    do {
        rv = get_server_line(conn);
        if (rv != APR_SUCCESS) {
            ms_bad_conn(ms, conn);
            return rv;
        }

        if (strncmp(MS_END, conn->buffer, MS_END_LEN) == 0) {
            rv = APR_SUCCESS;
            break;
        }
        else if (strncmp(MS_STAT, conn->buffer, MS_STAT_LEN) == 0) {
            update_stats(p, conn, ret);
            continue;
        }
        else {
            rv = APR_EGENERAL;
            break;
        }

    } while(1);

    ms_release_conn(ms, conn);

    if (stats) {
        *stats = ret;
    }

    return rv;
}

