/* 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 "testutil.h"
#include "apr.h"
#include "apu.h"
#include "apr_general.h"
#include "apr_strings.h"
#include "apr_hash.h"
#include "apr_memcache.h"
#include "apr_network_io.h"
#include "apr_thread_proc.h"

#if APR_HAVE_STDLIB_H
#include <stdlib.h>             /* for exit() */
#endif
#if APR_HAVE_PROCESS_H
#include <process.h>            /* for getpid() */
#endif

#define HOST "localhost"
#define PORT 11211

/* the total number of items to use for set/get testing */
#define TDATA_SIZE 3000

/* some smaller subset of TDATA_SIZE used for multiget testing */
#define TDATA_SET 100

/* our custom hash function just returns this all the time */
#define HASH_FUNC_RESULT 510

/* all keys will be prefixed with this */
const char prefix[] = "testmemcache";

/* text for values we store */
const char txt[] =
"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis at"
"lacus in ligula hendrerit consectetuer. Vestibulum tristique odio"
"iaculis leo. In massa arcu, ultricies a, laoreet nec, hendrerit non,"
"neque. Nulla sagittis sapien ac risus. Morbi ligula dolor, vestibulum"
"nec, viverra id, placerat dapibus, arcu. Curabitur egestas feugiat"
"tellus. Donec dignissim. Nunc ante. Curabitur id lorem. In mollis"
"tortor sit amet eros auctor dapibus. Proin nulla sem, tristique in,"
"convallis id, iaculis feugiat cras amet.";

/*
 * this datatype is for our custom server determination function. this might
 * be useful if you don't want to rely on simply hashing keys to determine
 * where a key belongs, but instead want to write something fancy, or use some
 * other kind of configuration data, i.e. a hash plus some data about a
 * namespace, or whatever. see my_server_func, and test_memcache_user_funcs
 * for the examples.
 */
typedef struct {
  const char *someval;
  apr_uint32_t which_server;
} my_hash_server_baton;


/* this could do something fancy and return some hash result.
 * for simplicity, just return the same value, so we can test it later on.
 * if you wanted to use some external hashing library or functions for
 * consistent hashing, for example, this would be a good place to do it.
 */
static apr_uint32_t my_hash_func(void *baton, const char *data,
                                 apr_size_t data_len)
{

  return HASH_FUNC_RESULT;
}

/*
 * a fancy function to determine which server to use given some kind of data
 * and a hash value. this example actually ignores the hash value itself
 * and pulls some number from the *baton, which is a struct that has some
 * kind of meaningful stuff in it.
 */
static apr_memcache_server_t *my_server_func(void *baton,
                                             apr_memcache_t *mc,
                                             const apr_uint32_t hash)
{
  apr_memcache_server_t *ms = NULL;
  my_hash_server_baton *mhsb = (my_hash_server_baton *)baton;

  if(mc->ntotal == 0) {
    return NULL;
  }

  if(mc->ntotal < mhsb->which_server) {
    return NULL;
  }

  ms = mc->live_servers[mhsb->which_server - 1];

  return ms;
}

apr_uint16_t firsttime = 0;
static int randval(apr_uint32_t high)
{
    apr_uint32_t i = 0;
    double d = 0;

    if (firsttime == 0) {
        srand((unsigned) (getpid()));
        firsttime = 1;
    }

    d = (double) rand() / ((double) RAND_MAX + 1);
    i = (int) (d * (high - 0 + 1));

    return i > 0 ? i : 1;
}

/* use apr_socket stuff to see if there is in fact a memcached server
 * running on PORT.
 */
static apr_status_t check_mc(void)
{
    apr_pool_t *pool = p;
    apr_status_t rv;
    apr_socket_t *sock = NULL;
    apr_sockaddr_t *sa;
    struct iovec vec[2];
    apr_size_t written;
    char buf[128];
    apr_size_t len;

    rv = apr_socket_create(&sock, APR_INET, SOCK_STREAM, 0, pool);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = apr_sockaddr_info_get(&sa, HOST, APR_INET, PORT, 0, pool);
    if (rv != APR_SUCCESS) {
        return rv;
    }

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

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

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

    vec[0].iov_base = "version";
    vec[0].iov_len = sizeof("version") - 1;

    vec[1].iov_base = "\r\n";
    vec[1].iov_len = sizeof("\r\n") - 1;

    rv = apr_socket_sendv(sock, vec, 2, &written);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    len = sizeof(buf);
    rv = apr_socket_recv(sock, buf, &len);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    if (strncmp(buf, "VERSION", sizeof("VERSION") - 1) != 0) {
        rv = APR_EGENERAL;
    }

    apr_socket_close(sock);
    return rv;
}

static int has_memcache_server(void)
{
    static int has_memcache_server_state = -1;

    if (has_memcache_server_state < 0) {
        apr_status_t rv;

        /* check for a running memcached on the typical port before
         * trying to run the tests. succeed if we don't find one.
         */
        rv = check_mc();
        if (rv == APR_SUCCESS) {
            has_memcache_server_state = 1;
        }
        else {
            has_memcache_server_state = 0;
            abts_log_message("Error %d occurred attempting to reach memcached "
                             "on %s:%d.  Skipping apr_memcache tests...",
                             rv, HOST, PORT);
        }
    }

    return has_memcache_server_state;
}
/*
 * general test to make sure we can create the memcache struct and add
 * some servers, but not more than we tell it we can add
 */

static void test_memcache_create(abts_case * tc, void *data)
{
  apr_pool_t *pool = p;
  apr_status_t rv;
  apr_memcache_t *memcache;
  apr_memcache_server_t *server, *s;
  apr_uint32_t max_servers = 10;
  apr_uint32_t i;
  apr_uint32_t hash;

  if (!has_memcache_server()) {
      ABTS_SKIP(tc, data, "Memcache server not found.");
      return;
  }

  rv = apr_memcache_create(pool, max_servers, 0, &memcache);
  ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

  for (i = 1; i <= max_servers; i++) {
    apr_port_t port;

    port = PORT + i;
    rv =
      apr_memcache_server_create(pool, HOST, PORT + i, 0, 1, 1, 60, &server);
    ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

    rv = apr_memcache_add_server(memcache, server);
    ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);

    s = apr_memcache_find_server(memcache, HOST, port);
    ABTS_PTR_EQUAL(tc, server, s);

    rv = apr_memcache_disable_server(memcache, s);
    ABTS_ASSERT(tc, "server disable failed", rv == APR_SUCCESS);

    rv = apr_memcache_enable_server(memcache, s);
    ABTS_ASSERT(tc, "server enable failed", rv == APR_SUCCESS);

    hash = apr_memcache_hash(memcache, prefix, strlen(prefix));
    ABTS_ASSERT(tc, "hash failed", hash > 0);

    s = apr_memcache_find_server_hash(memcache, hash);
    ABTS_PTR_NOTNULL(tc, s);
  }

  rv = apr_memcache_server_create(pool, HOST, PORT, 0, 1, 1, 60, &server);
  ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

  rv = apr_memcache_add_server(memcache, server);
  ABTS_ASSERT(tc, "server add should have failed", rv != APR_SUCCESS);

}

/* install our own custom hashing and server selection routines. */

static int create_test_hash(apr_pool_t *p, apr_hash_t *h)
{
  int i;

  for (i = 0; i < TDATA_SIZE; i++) {
    char *k, *v;

    k = apr_pstrcat(p, prefix, apr_itoa(p, i), NULL);
    v = apr_pstrndup(p, txt, randval((apr_uint32_t)strlen(txt)));

    apr_hash_set(h, k, APR_HASH_KEY_STRING, v);
  }

  return i;
}

static void test_memcache_user_funcs(abts_case * tc, void *data)
{
  apr_pool_t *pool = p;
  apr_status_t rv;
  apr_memcache_t *memcache;
  apr_memcache_server_t *found;
  apr_uint32_t max_servers = 10;
  apr_uint32_t hres;
  apr_uint32_t i;
  my_hash_server_baton *baton =
    apr_pcalloc(pool, sizeof(my_hash_server_baton));

  if (!has_memcache_server()) {
      ABTS_SKIP(tc, data, "Memcache server not found.");
      return;
  }

  rv = apr_memcache_create(pool, max_servers, 0, &memcache);
  ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

  /* as noted above, install our custom hash function, and call
   * apr_memcache_hash. the return value should be our predefined number,
   * and our function just ignores the other args, for simplicity.
   */
  memcache->hash_func = my_hash_func;

  hres = apr_memcache_hash(memcache, "whatever", sizeof("whatever") - 1);
  ABTS_INT_EQUAL(tc, HASH_FUNC_RESULT, hres);

  /* add some servers */
  for(i = 1; i <= 10; i++) {
    apr_memcache_server_t *ms;

    rv = apr_memcache_server_create(pool, HOST, i, 0, 1, 1, 60, &ms);
    ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

    rv = apr_memcache_add_server(memcache, ms);
    ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);
  }

  /*
   * set 'which_server' in our server_baton to find the third server
   * which should have the same port.
   */
  baton->which_server = 3;
  memcache->server_func = my_server_func;
  memcache->server_baton = baton;
  found = apr_memcache_find_server_hash(memcache, 0);
  ABTS_ASSERT(tc, "wrong server found", found->port == baton->which_server);
}

/* test non data related commands like stats and version */
static void test_memcache_meta(abts_case * tc, void *data)
{
    apr_pool_t *pool = p;
    apr_memcache_t *memcache;
    apr_memcache_server_t *server;
    apr_memcache_stats_t *stats;
    char *result;
    apr_status_t rv;

    if (!has_memcache_server()) {
        ABTS_SKIP(tc, data, "Memcache server not found.");
        return;
    }

    rv = apr_memcache_create(pool, 1, 0, &memcache);
    ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

    rv = apr_memcache_server_create(pool, HOST, PORT, 0, 1, 1, 60, &server);
    ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

    rv = apr_memcache_add_server(memcache, server);
    ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);

    apr_memcache_version(server, pool, &result);
    ABTS_PTR_NOTNULL(tc, result);

    apr_memcache_stats(server, p, &stats);
    ABTS_PTR_NOTNULL(tc, stats);

    ABTS_STR_NEQUAL(tc, stats->version, result, 5);

    /*
     * no way to know exactly what will be in most of these, so
     * just make sure there is something.
     */

    ABTS_ASSERT(tc, "pid", stats->pid >= 0);
    ABTS_ASSERT(tc, "time", stats->time >= 0);
    /* ABTS_ASSERT(tc, "pointer_size", stats->pointer_size >= 0); */
    ABTS_ASSERT(tc, "rusage_user", stats->rusage_user >= 0);
    ABTS_ASSERT(tc, "rusage_system", stats->rusage_system >= 0);

    ABTS_ASSERT(tc, "curr_items", stats->curr_items >= 0);
    ABTS_ASSERT(tc, "total_items", stats->total_items >= 0);
    ABTS_ASSERT(tc, "bytes", stats->bytes >= 0);

    ABTS_ASSERT(tc, "curr_connections", stats->curr_connections >= 0);
    ABTS_ASSERT(tc, "total_connections", stats->total_connections >= 0);
    ABTS_ASSERT(tc, "connection_structures",
                stats->connection_structures >= 0);

    ABTS_ASSERT(tc, "cmd_get", stats->cmd_get >= 0);
    ABTS_ASSERT(tc, "cmd_set", stats->cmd_set >= 0);
    ABTS_ASSERT(tc, "get_hits", stats->get_hits >= 0);
    ABTS_ASSERT(tc, "get_misses", stats->get_misses >= 0);

    /* ABTS_ASSERT(tc, "evictions", stats->evictions >= 0); */

    ABTS_ASSERT(tc, "bytes_read", stats->bytes_read >= 0);
    ABTS_ASSERT(tc, "bytes_written", stats->bytes_written >= 0);
    ABTS_ASSERT(tc, "limit_maxbytes", stats->limit_maxbytes >= 0);

    /* ABTS_ASSERT(tc, "threads", stats->threads >= 0); */
}

/* test add and replace calls */

static void test_memcache_addreplace(abts_case * tc, void *data)
{
 apr_pool_t *pool = p;
 apr_status_t rv;
 apr_memcache_t *memcache;
 apr_memcache_server_t *server;
 apr_hash_t *tdata;
 apr_hash_index_t *hi;
 char *result;
 apr_size_t len;

  if (!has_memcache_server()) {
      ABTS_SKIP(tc, data, "Memcache server not found.");
      return;
  }
 
  rv = apr_memcache_create(pool, 1, 0, &memcache);
  ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

  rv = apr_memcache_server_create(pool, HOST, PORT, 0, 1, 1, 60, &server);
  ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

  rv = apr_memcache_add_server(memcache, server);
  ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);

  tdata = apr_hash_make(p);
  create_test_hash(pool, tdata);

  for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) {
    const void *k;
    void *v;
    const char *key;

    apr_hash_this(hi, &k, NULL, &v);
    key = k;

    /* doesn't exist yet, fail */
    rv = apr_memcache_replace(memcache, key, v, strlen(v) - 1, 0, 27);
    ABTS_ASSERT(tc, "replace should have failed", rv != APR_SUCCESS);

    /* doesn't exist yet, succeed */
    rv = apr_memcache_add(memcache, key, v, strlen(v), 0, 27);
    ABTS_ASSERT(tc, "add failed", rv == APR_SUCCESS);

    /* exists now, succeed */
    rv = apr_memcache_replace(memcache, key, "new", sizeof("new") - 1, 0, 27);
    ABTS_ASSERT(tc, "replace failed", rv == APR_SUCCESS);

    /* make sure its different */
    rv = apr_memcache_getp(memcache, pool, key, &result, &len, NULL);
    ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS);
    ABTS_STR_NEQUAL(tc, result, "new", 3);

    /* exists now, fail */
    rv = apr_memcache_add(memcache, key, v, strlen(v), 0, 27);
    ABTS_ASSERT(tc, "add should have failed", rv != APR_SUCCESS);

    /* clean up */
    rv = apr_memcache_delete(memcache, key, 0);
    ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS);
  }
}

/* basic tests of the increment and decrement commands */
static void test_memcache_incrdecr(abts_case * tc, void *data)
{
 apr_pool_t *pool = p;
 apr_status_t rv;
 apr_memcache_t *memcache;
 apr_memcache_server_t *server;
 apr_uint32_t new;
 char *result;
 apr_size_t len;
 apr_uint32_t i;

  if (!has_memcache_server()) {
      ABTS_SKIP(tc, data, "Memcache server not found.");
      return;
  }
 
  rv = apr_memcache_create(pool, 1, 0, &memcache);
  ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

  rv = apr_memcache_server_create(pool, HOST, PORT, 0, 1, 1, 60, &server);
  ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

  rv = apr_memcache_add_server(memcache, server);
  ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);

  rv = apr_memcache_set(memcache, prefix, "271", sizeof("271") - 1, 0, 27);
  ABTS_ASSERT(tc, "set failed", rv == APR_SUCCESS);

  for( i = 1; i <= TDATA_SIZE; i++) {
    apr_uint32_t expect;

    rv = apr_memcache_getp(memcache, pool, prefix, &result, &len, NULL);
    ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS);

    expect = i + atoi(result);

    rv = apr_memcache_incr(memcache, prefix, i, &new);
    ABTS_ASSERT(tc, "incr failed", rv == APR_SUCCESS);

    ABTS_INT_EQUAL(tc, expect, new);

    rv = apr_memcache_decr(memcache, prefix, i, &new);
    ABTS_ASSERT(tc, "decr failed", rv == APR_SUCCESS);
    ABTS_INT_EQUAL(tc, atoi(result), new);

  }

  rv = apr_memcache_getp(memcache, pool, prefix, &result, &len, NULL);
  ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS);

  ABTS_INT_EQUAL(tc, 271, atoi(result));

  rv = apr_memcache_delete(memcache, prefix, 0);
  ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS);
}

/* test the multiget functionality */
static void test_memcache_multiget(abts_case * tc, void *data)
{
  apr_pool_t *pool = p;
  apr_pool_t *tmppool;
  apr_status_t rv;
  apr_memcache_t *memcache;
  apr_memcache_server_t *server;
  apr_hash_t *tdata, *values;
  apr_hash_index_t *hi;
  apr_uint32_t i;

  if (!has_memcache_server()) {
      ABTS_SKIP(tc, data, "Memcache server not found.");
      return;
  }

  rv = apr_memcache_create(pool, 1, 0, &memcache);
  ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

  rv = apr_memcache_server_create(pool, HOST, PORT, 0, 1, 1, 60, &server);
  ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

  rv = apr_memcache_add_server(memcache, server);
  ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);

  values = apr_hash_make(p);
  tdata = apr_hash_make(p);

  create_test_hash(pool, tdata);

  for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) {
    const void *k;
    void *v;
    const char *key;

    apr_hash_this(hi, &k, NULL, &v);
    key = k;

    rv = apr_memcache_set(memcache, key, v, strlen(v), 0, 27);
    ABTS_ASSERT(tc, "set failed", rv == APR_SUCCESS);
  }

  apr_pool_create(&tmppool, pool);
  for (i = 0; i < TDATA_SET; i++)
    apr_memcache_add_multget_key(pool,
                                 apr_pstrcat(pool, prefix,
                                             apr_itoa(pool, i), NULL),
                                 &values);

  rv = apr_memcache_multgetp(memcache,
                             tmppool,
                             pool,
                             values);

  ABTS_ASSERT(tc, "multgetp failed", rv == APR_SUCCESS);
  ABTS_ASSERT(tc, "multgetp returned too few results",
              apr_hash_count(values) == TDATA_SET);

  for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) {
    const void *k;
    const char *key;

    apr_hash_this(hi, &k, NULL, NULL);
    key = k;

    rv = apr_memcache_delete(memcache, key, 0);
    ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS);
  }

}

/* test setting and getting */

static void test_memcache_setget(abts_case * tc, void *data)
{
    apr_pool_t *pool = p;
    apr_status_t rv;
    apr_memcache_t *memcache;
    apr_memcache_server_t *server;
    apr_hash_t *tdata;
    apr_hash_index_t *hi;
    char *result;
    apr_size_t len;

    if (!has_memcache_server()) {
        ABTS_SKIP(tc, data, "Memcache server not found.");
        return;
    }

    rv = apr_memcache_create(pool, 1, 0, &memcache);
    ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

    rv = apr_memcache_server_create(pool, HOST, PORT, 0, 1, 1, 60, &server);
    ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

    rv = apr_memcache_add_server(memcache, server);
    ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);

    tdata = apr_hash_make(pool);

    create_test_hash(pool, tdata);

    for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) {
        const void *k;
        void *v;
        const char *key;

        apr_hash_this(hi, &k, NULL, &v);
        key = k;

        rv = apr_memcache_set(memcache, key, v, strlen(v), 0, 27);
        ABTS_ASSERT(tc, "set failed", rv == APR_SUCCESS);
        rv = apr_memcache_getp(memcache, pool, key, &result, &len, NULL);
        ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS);
    }

    rv = apr_memcache_getp(memcache, pool, "nothere3423", &result, &len, NULL);

    ABTS_ASSERT(tc, "get should have failed", rv != APR_SUCCESS);

    for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) {
        const void *k;
        const char *key;

        apr_hash_this(hi, &k, NULL, NULL);
        key = k;

        rv = apr_memcache_delete(memcache, key, 0);
        ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS);
    }
}

abts_suite *testmemcache(abts_suite * suite)
{
    suite = ADD_SUITE(suite);
    abts_run_test(suite, test_memcache_create, NULL);
    abts_run_test(suite, test_memcache_user_funcs, NULL);
    abts_run_test(suite, test_memcache_meta, NULL);
    abts_run_test(suite, test_memcache_setget, NULL);
    abts_run_test(suite, test_memcache_multiget, NULL);
    abts_run_test(suite, test_memcache_addreplace, NULL);
    abts_run_test(suite, test_memcache_incrdecr, NULL);

    return suite;
}
