/* ====================================================================
*    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_strings.h>

#include "serf.h"
#include "serf_bucket_util.h"
#include "serf_private.h"

/* Use a linked list to store the config values, as we'll only store a couple
   of values per context. */
struct serf__config_hdr_t {
    struct config_entry_t *first;
};

typedef void (*config_free_cb_t)(serf_bucket_alloc_t *alloc, void *value);

typedef struct config_entry_t {
    apr_uint32_t key;
    void *value;
    struct config_entry_t *next;
    config_free_cb_t free_cb;
} config_entry_t;

static serf__config_hdr_t *create_config_hdr(serf_bucket_alloc_t *allocator)
{
    serf__config_hdr_t *hdr = serf_bucket_mem_calloc(allocator, sizeof(*hdr));
    return hdr;
}

static apr_status_t
add_or_replace_entry(serf_config_t *config,
                     serf__config_hdr_t *hdr, serf_config_key_t key, void *value,
                     config_free_cb_t free_cb)
{
    config_entry_t *iter = hdr->first;
    config_entry_t *last = iter;
    int found = FALSE;

    /* Find the entry with the matching key. If it exists, replace its value. */
    while (iter != NULL) {
        if (iter->key == key) {
            found = TRUE;
            break;
        }
        last = iter;
        iter = iter->next;
    }

    if (found) {
        iter->key = key;
        if (iter->free_cb)
            iter->free_cb(config->allocator, iter->value);
        iter->value = value;
        iter->free_cb = free_cb;
    } else {
        /* Not found, create a new entry and append it to the list. */
        config_entry_t *entry = serf_bucket_mem_alloc(config->allocator,
                                                      sizeof(*entry));

        entry->key = key;
        entry->value = value;
        entry->free_cb = free_cb;
        entry->next = NULL;

        if (last)
            last->next = entry;
        else
            hdr->first = entry;
    }

    return APR_SUCCESS;
}

static apr_status_t config_set_object(serf_config_t *config,
                                      serf_config_key_t key,
                                      void *value,
                                      config_free_cb_t free_cb)
{
    serf__config_hdr_t *target;

    /* Set the value in the hash table of the selected category */
    if (key & SERF_CONFIG_PER_CONTEXT) {
        target = config->per_context;
    }
    else if (key & SERF_CONFIG_PER_HOST) {
        target = config->per_host;
    }
    else {
        target = config->per_conn;
    }

    if (!target) {
        /* Config object doesn't manage keys in this category */
        return APR_EINVAL;
    }

    return add_or_replace_entry(config, target, key, value, free_cb);
}

static void cleanup_hdr(serf__config_store_t *store, serf__config_hdr_t *hdr)
{
    config_entry_t *e = hdr->first;

    serf_bucket_mem_free(store->allocator, hdr);

    while (e) {
        config_entry_t *next = e->next;

        if (e->free_cb)
            e->free_cb(store->allocator, e->value);

        serf_bucket_mem_free(store->allocator, e);
        e = next;
    }
}

static apr_status_t cleanup_store(void *baton)
{
    serf__config_store_t *store = baton;
    apr_hash_index_t *hi;

    for (hi = apr_hash_first(store->pool, store->global_per_host);
         hi;
         hi = apr_hash_next(hi))
      {
          const void *key;
          void *val;

          apr_hash_this(hi, &key, NULL, &val);

          serf_bucket_mem_free(store->allocator, (void *)key);

          cleanup_hdr(store, val);
      }

    for (hi = apr_hash_first(store->pool, store->global_per_conn);
         hi;
         hi = apr_hash_next(hi))
      {
          const void *key;
          void *val;

          apr_hash_this(hi, &key, NULL, &val);

          serf_bucket_mem_free(store->allocator, (void *)key);

          cleanup_hdr(store, val);
      }

    cleanup_hdr(store, store->global_per_context);

    return APR_SUCCESS;
}

/*** Config Store ***/
apr_status_t serf__config_store_init(serf_context_t *ctx)
{
    apr_pool_t *pool = ctx->pool;
    serf_bucket_alloc_t *alloc = serf_bucket_allocator_create(pool,
                                                              NULL, NULL);

    ctx->config_store.pool = pool;
    ctx->config_store.allocator = alloc;
    ctx->config_store.global_per_context = create_config_hdr(alloc);
    ctx->config_store.global_per_host = apr_hash_make(pool);
    ctx->config_store.global_per_conn = apr_hash_make(pool);

    apr_pool_cleanup_register(pool, &ctx->config_store, cleanup_store,
                              apr_pool_cleanup_null);

    return APR_SUCCESS;
}

/* Defines the key to use for per host settings */
static const char * host_key_for_conn(serf_connection_t *conn,
                                      apr_pool_t *pool)
{
    /* SCHEME://HOSTNAME:PORT, e.g. http://localhost:12345 */
    return conn->host_url;
}

/* Defines the key to use for per connection settings */
static const char * conn_key_for_conn(serf_connection_t *conn,
                                      apr_pool_t *pool)
{
    /* Key needs to be unique per connection, so stringify its pointer value */
    return apr_psprintf(pool, "%pp", conn);
}

/* Defines the key to use for per connection settings */
static const char * conn_key_for_client(serf_incoming_t *incoming,
                                        apr_pool_t *pool)
{
    /* Key needs to be unique per connection, so stringify its pointer value */
    return apr_psprintf(pool, "%pp", incoming);
}

/* Defines the key to use for per connection settings */
static const char * conn_key_for_listener(serf_listener_t *listener,
                                          apr_pool_t *pool)
{
    /* Key needs to be unique per connection, so stringify its pointer value */
    return apr_psprintf(pool, "%pp", listener);
}

apr_status_t serf__config_store_create_ctx_config(serf_context_t *ctx,
                                                  serf_config_t **config)
{
    serf__config_store_t *config_store = &ctx->config_store;

    serf_config_t *cfg = apr_pcalloc(ctx->pool, sizeof(serf_config_t));
    cfg->ctx_pool = config_store->pool;
    cfg->allocator = config_store->allocator;
    cfg->per_context = config_store->global_per_context;

    *config = cfg;
    return APR_SUCCESS;
}

apr_status_t serf__config_store_create_conn_config(serf_connection_t *conn,
                                                   serf_config_t **config)
{
    serf__config_store_t *config_store = &conn->ctx->config_store;
    const char *host_key, *conn_key;
    serf__config_hdr_t *per_conn, *per_host;
    apr_pool_t *tmp_pool;
    apr_status_t status;

    serf_config_t *cfg = apr_pcalloc(conn->pool, sizeof(serf_config_t));
    cfg->ctx_pool = config_store->pool;
    cfg->allocator = config_store->allocator;
    cfg->per_context = config_store->global_per_context;

    if ((status = apr_pool_create(&tmp_pool, cfg->ctx_pool)) != APR_SUCCESS)
        return status;

    /* Find the config values for this connection, create empty structure
        if needed */
    conn_key = conn_key_for_conn(conn, tmp_pool);
    per_conn = apr_hash_get(config_store->global_per_conn, conn_key,
                            APR_HASH_KEY_STRING);
    if (!per_conn) {
        per_conn = create_config_hdr(cfg->allocator);
        apr_hash_set(config_store->global_per_conn,
                     serf_bstrdup(cfg->allocator, conn_key),
                     APR_HASH_KEY_STRING, per_conn);
    }
    cfg->per_conn = per_conn;

    /* Find the config values for this host, create empty structure
        if needed */
    host_key = host_key_for_conn(conn, tmp_pool);
    per_host = apr_hash_get(config_store->global_per_host,
                            host_key,
                            APR_HASH_KEY_STRING);
    if (!per_host) {
        per_host = create_config_hdr(cfg->allocator);
        apr_hash_set(config_store->global_per_host,
                     serf_bstrdup(cfg->allocator, host_key),
                     APR_HASH_KEY_STRING, per_host);
    }
    cfg->per_host = per_host;

    apr_pool_destroy(tmp_pool);

    *config = cfg;

    return APR_SUCCESS;
}

apr_status_t serf__config_store_create_client_config(serf_incoming_t *client,
                                                     serf_config_t **config)
{
    serf__config_store_t *config_store = &client->ctx->config_store;
    const char *client_key;
    serf__config_hdr_t *per_conn;
    apr_pool_t *tmp_pool;
    apr_status_t status;

    serf_config_t *cfg = apr_pcalloc(client->pool, sizeof(serf_config_t));
    cfg->ctx_pool = config_store->pool;
    cfg->allocator = config_store->allocator;
    cfg->per_context = config_store->global_per_context;

    if ((status = apr_pool_create(&tmp_pool, client->pool)) != APR_SUCCESS)
        return status;

    /* Find the config values for this connection, create empty structure
    if needed */
    client_key = conn_key_for_client(client, tmp_pool);
    per_conn = apr_hash_get(config_store->global_per_conn, client_key,
                            APR_HASH_KEY_STRING);
    if (!per_conn) {
        per_conn = create_config_hdr(cfg->allocator);
        apr_hash_set(config_store->global_per_conn,
                     serf_bstrdup(cfg->allocator, client_key),
                     APR_HASH_KEY_STRING, per_conn);
    }
    cfg->per_conn = per_conn;
    cfg->per_host = NULL;

    apr_pool_destroy(tmp_pool);

    *config = cfg;

    return APR_SUCCESS;
}

apr_status_t serf__config_store_create_listener_config(serf_listener_t *listener,
                                                       serf_config_t **config)
{
    serf__config_store_t *config_store = &listener->ctx->config_store;
    const char *client_key;
    serf__config_hdr_t *per_conn;
    apr_pool_t *tmp_pool;
    apr_status_t status;

    serf_config_t *cfg = apr_pcalloc(listener->pool, sizeof(serf_config_t));
    cfg->ctx_pool = config_store->pool;
    cfg->allocator = config_store->allocator;
    cfg->per_context = config_store->global_per_context;

    if ((status = apr_pool_create(&tmp_pool, listener->pool)) != APR_SUCCESS)
        return status;

    /* Find the config values for this connection, create empty structure
    if needed */
    client_key = conn_key_for_listener(listener, tmp_pool);
    per_conn = apr_hash_get(config_store->global_per_conn, client_key,
                            APR_HASH_KEY_STRING);
    if (!per_conn) {
        per_conn = create_config_hdr(cfg->allocator);
        apr_hash_set(config_store->global_per_conn,
                     serf_bstrdup(cfg->allocator, client_key),
                     APR_HASH_KEY_STRING, per_conn);
    }
    cfg->per_conn = per_conn;
    cfg->per_host = NULL;

    apr_pool_destroy(tmp_pool);

    *config = cfg;

    return APR_SUCCESS;
}

apr_status_t
serf__config_store_remove_connection(serf__config_store_t config_store,
                                     serf_connection_t *conn)
{
    return APR_ENOTIMPL; /* Mem leak? */
}

apr_status_t
serf__config_store_remove_client(serf__config_store_t config_store,
                                 serf_incoming_t *client)
{
    return APR_ENOTIMPL; /* Mem leak? */
}


apr_status_t
serf__config_store_remove_host(serf__config_store_t config_store,
                               const char *hostname_port)
{
    return APR_ENOTIMPL; /* Mem leak? */
}

/*** Config ***/
apr_status_t serf_config_set_string(serf_config_t *config,
                                    serf_config_key_t key,
                                    const char *value)
{
    /* Cast away const is ok here, the callers should always use
       serf_config_get_string for this key. */
    return serf_config_set_object(config, key, (void *)value);
}

apr_status_t serf_config_set_stringc(serf_config_t *config,
                                     serf_config_key_t key,
                                     const char *value)
{
    char *cvalue;

    cvalue = serf_bstrdup(config->allocator, value);

    return config_set_object(config, key, cvalue,
                             serf_bucket_mem_free);
}

apr_status_t serf_config_set_stringf(serf_config_t *config,
                                     serf_config_key_t key,
                                     apr_pool_t *scratch_pool,
                                     const char *fmt, ...)
{
    va_list argp;
    char *cvalue;

    va_start(argp, fmt);
    cvalue = apr_pvsprintf(scratch_pool, fmt, argp);
    va_end(argp);

    return serf_config_set_stringc(config, key, cvalue);
}

apr_status_t serf_config_set_object(serf_config_t *config,
                                    serf_config_key_t key,
                                    void *value)
{
    return config_set_object(config, key, value, NULL);
}

apr_status_t serf_config_get_string(serf_config_t *config,
                                    serf_config_key_t key,
                                    const char **value)
{
    return serf_config_get_object(config, key, (void**)value);
}

apr_status_t serf_config_get_object(serf_config_t *config,
                                    serf_config_key_t key,
                                    void **value)
{
    serf__config_hdr_t *target;

    if (config == NULL) {
        *value = NULL;
        return APR_EINVAL;
    }
    if (key & SERF_CONFIG_PER_CONTEXT)
        target = config->per_context;
    else if (key & SERF_CONFIG_PER_HOST)
        target = config->per_host;
    else
        target = config->per_conn;

    *value = NULL;
    if (target) {
        config_entry_t *iter = target->first;
        /* Find the matching key and return its value */
        while (iter != NULL) {
            if (iter->key == key) {
                *value = iter->value;
                return APR_SUCCESS;
            }
            iter = iter->next;
        }
        return APR_SUCCESS;
    } else {
        /* Config object doesn't manage keys in this category */
        return APR_EINVAL;
    }
}

apr_status_t serf_config_remove_value(serf_config_t *config,
                                      serf_config_key_t key)
{
    return serf_config_set_object(config, key, NULL);
}

struct ssl_session_data
{
    unsigned char *session;
    apr_size_t session_len;
};

#define SERF_CONFIG__SSL_SESSION       (SERF_CONFIG_PER_HOST | 0xF00001)

apr_status_t
serf__config_store_set_ssl_session(serf_config_t *config,
                                   const unsigned char *session,
                                   apr_size_t session_len)
{
    struct ssl_session_data *ssld = serf_bucket_mem_alloc(config->allocator,
                                                          sizeof(*ssld)
                                                          + session_len);

    ssld->session = ((unsigned char *)ssld) + sizeof(*ssld);
    ssld->session_len = session_len;

    memcpy(ssld->session, session, session_len);

    return config_set_object(config, SERF_CONFIG__SSL_SESSION, ssld,
                             serf_bucket_mem_free);
}

apr_status_t
serf__config_store_get_ssl_session(serf_config_t *config,
                                   const unsigned char **session,
                                   apr_size_t *session_len)
{
    const struct ssl_session_data *ssld;
    apr_status_t status;
    void *value;

    status = serf_config_get_object(config, SERF_CONFIG__SSL_SESSION, &value);

    if (status)
        return status;
    else if (!value)
        return APR_ENOENT;

    ssld = value;

    *session = ssld->session;
    *session_len = ssld->session_len;
    return APR_SUCCESS;
}
