
/*
 * Copyright (C) Igor Sysoev
 */


#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>


#if 0

static ngx_http_module_t  ngx_http_cache_module_ctx = {
    NULL,                                  /* pre conf */

    NULL,                                  /* create main configuration */
    NULL,                                  /* init main configuration */

    NULL,                                  /* create server configuration */
    NULL,                                  /* merge server configuration */

    NULL,                                  /* create location configuration */
    NULL                                   /* merge location configuration */
};


ngx_module_t  ngx_http_cache_module = {
    NGX_MODULE,
    &ngx_http_cache_module_ctx,            /* module context */
    NULL,                                  /* module directives */
    NGX_HTTP_MODULE,                       /* module type */
    NULL,                                  /* init module */
    NULL                                   /* init process */
};

#endif


static ngx_int_t ngx_http_cache_create(ngx_http_request_t *r)
{
    ngx_str_t  *key;

    if (!(r->cache = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)))) {
        return NGX_ERROR;
    }

    if (ngx_array_init(&r->cache->key, r->pool, 5, sizeof(ngx_str_t))
                                                                  == NGX_ERROR)
    {
        return NGX_ERROR;
    }

    /* preallocate the primary key */

    if (!(key = ngx_array_push(&r->cache->key))) {
        return NGX_ERROR;
    }

    key->len = 0;
    key->data = NULL;

    /*
     * we use offsetof() because sizeof() pads the struct size to the int size
     */

    r->cache->header_size = offsetof(ngx_http_cache_header_t, key);

    r->cache->log = r->connection->log;
    r->cache->file.log = r->connection->log;

    return NGX_OK;
}


ngx_int_t ngx_http_cache_get(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx)
{
    ngx_str_t         *key;
    ngx_http_cache_t  *c;

    if (r->cache == NULL) {
        if (ngx_http_cache_create(r) == NGX_ERROR) {
            return NGX_ABORT;
        }
    }

    c = r->cache;
    key = c->key.elts;

    if (ctx->primary) {
        key[0] = ctx->key;
        c->header_size += ctx->key.len;
        c->key_len += ctx->key.len;
        c->buf = ctx->buf;

    } else {
        if (key[0].len == 0) {
            key[0] = r->uri;
            c->header_size += r->uri.len;
            c->key_len += ctx->key.len;
        }

        if (!(key = ngx_array_push(&r->cache->key))) {
            return NGX_ABORT;
        }

        c->header_size += ctx->key.len;
        c->key_len += ctx->key.len;
    }

#if 0

    if (ctx->memory) {
        ngx_http_memory_cache_get(r, ctx);
    }

#endif

    if (ctx->file) {
        return ngx_http_file_cache_get(r, ctx);
    }

    return NGX_DECLINED;
}


#if 0


ngx_http_cache_t *ngx_http_cache_get(ngx_http_cache_hash_t *hash,
                                     ngx_http_cleanup_t *cleanup,
                                     ngx_str_t *key, uint32_t *crc)
{
    ngx_uint_t         i;
    ngx_http_cache_t  *c;

    *crc = ngx_crc(key->data, key->len);

    c = hash->elts + *crc % hash->hash * hash->nelts;

    if (ngx_mutex_lock(&hash->mutex) == NGX_ERROR) {
        return (void *) NGX_ERROR;
    }

    for (i = 0; i < hash->nelts; i++) {
        if (c[i].crc == *crc
            && c[i].key.len == key->len
            && ngx_rstrncmp(c[i].key.data, key->data, key->len) == 0)
        {
#if 0
            if (c[i].expired) {
                ngx_mutex_unlock(&hash->mutex);
                return (void *) NGX_AGAIN;
            }
#endif

            c[i].refs++;

            if ((!(c[i].notify && (ngx_event_flags & NGX_USE_KQUEUE_EVENT)))
                && (ngx_cached_time - c[i].updated >= hash->update))
            {
                c[i].expired = 1;
            }

            ngx_mutex_unlock(&hash->mutex);

            if (cleanup) {
                cleanup->data.cache.hash = hash;
                cleanup->data.cache.cache = &c[i];
                cleanup->valid = 1;
                cleanup->cache = 1;
            }

            return &c[i];
        }
    }

    ngx_mutex_unlock(&hash->mutex);

    return NULL;
}


ngx_http_cache_t *ngx_http_cache_alloc(ngx_http_cache_hash_t *hash,
                                       ngx_http_cache_t *cache,
                                       ngx_http_cleanup_t *cleanup,
                                       ngx_str_t *key, uint32_t crc,
                                       ngx_str_t *value, ngx_log_t *log)
{
    time_t             old;
    ngx_uint_t         i;
    ngx_http_cache_t  *c;

    old = ngx_cached_time + 1;

    c = hash->elts + crc % hash->hash * hash->nelts;

    if (ngx_mutex_lock(&hash->mutex) == NGX_ERROR) {
        return (void *) NGX_ERROR;
    }

    if (cache == NULL) {

        /* allocate a new entry */

        for (i = 0; i < hash->nelts; i++) {
            if (c[i].refs > 0) {
                /* a busy entry */
                continue;
            }

            if (c[i].key.len == 0) {
                /* a free entry is found */
                cache = &c[i];
                break;
            }

            /* looking for the oldest cache entry */

            if (old > c[i].accessed) {

                old = c[i].accessed;
                cache = &c[i];
            }
        }

        if (cache == NULL) {
            ngx_mutex_unlock(&hash->mutex);
            return NULL;
        }

        ngx_http_cache_free(cache, key, value, log);

        if (cache->key.data == NULL) {
            cache->key.data = ngx_alloc(key->len, log);
            if (cache->key.data == NULL) {
                ngx_http_cache_free(cache, NULL, NULL, log);
                ngx_mutex_unlock(&hash->mutex);
                return NULL;
            }
        }

        cache->key.len = key->len;
        ngx_memcpy(cache->key.data, key->data, key->len);

    } else if (value) {
        ngx_http_cache_free(cache, key, value, log);
    }

    if (value) {
        if (cache->data.value.data == NULL) {
            cache->data.value.data = ngx_alloc(value->len, log);
            if (cache->data.value.data == NULL) {
                ngx_http_cache_free(cache, NULL, NULL, log);
                ngx_mutex_unlock(&hash->mutex);
                return NULL;
            }
        }

        cache->data.value.len = value->len;
        ngx_memcpy(cache->data.value.data, value->data, value->len);
    }

    cache->crc = crc;
    cache->key.len = key->len;

    cache->refs = 1;
    cache->count = 0;

    cache->deleted = 0;
    cache->expired = 0;
    cache->memory = 0;
    cache->mmap = 0;
    cache->notify = 0;

    if (cleanup) {
        cleanup->data.cache.hash = hash;
        cleanup->data.cache.cache = cache;
        cleanup->valid = 1;
        cleanup->cache = 1;
    }

    ngx_mutex_unlock(&hash->mutex);

    return cache;
}


void ngx_http_cache_free(ngx_http_cache_t *cache,
                         ngx_str_t *key, ngx_str_t *value, ngx_log_t *log)
{
    if (cache->memory) {
        if (cache->data.value.data
            && (value == NULL || value->len > cache->data.value.len))
        {
            ngx_free(cache->data.value.data);
            cache->data.value.data = NULL;
        }
    }

    /* TODO: mmap */

    cache->data.value.len = 0;

    if (cache->fd != NGX_INVALID_FILE) {

        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
                       "http cache close fd: %d", cache->fd);

        if (ngx_close_file(cache->fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                          ngx_close_file_n " \"%s\" failed",
                          cache->key.data);
        }

        cache->fd = NGX_INVALID_FILE;
    }

    if (cache->key.data && (key == NULL || key->len > cache->key.len)) {
        ngx_free(cache->key.data);
        cache->key.data = NULL;
    }

    cache->key.len = 0;

    cache->refs = 0;
}


void ngx_http_cache_lock(ngx_http_cache_hash_t *hash, ngx_http_cache_t *cache)
{
    if (ngx_mutex_lock(&hash->mutex) == NGX_ERROR) {
        return;
    }
}


void ngx_http_cache_unlock(ngx_http_cache_hash_t *hash,
                           ngx_http_cache_t *cache, ngx_log_t *log)
{
    if (ngx_mutex_lock(&hash->mutex) == NGX_ERROR) {
        return;
    }

    cache->refs--;

    if (cache->refs == 0 && cache->deleted) {
        ngx_http_cache_free(cache, NULL, NULL, log);
    }

    ngx_mutex_unlock(&hash->mutex);
}


#if 0

ngx_http_cache_add_file_event(ngx_http_cache_hash_t *hash,
                              ngx_http_cache_t *cache)
{
    ngx_event_t                 *ev;
    ngx_http_cache_event_ctx_t  *ctx;

    ev = &ngx_cycle->read_events[fd];
    ngx_memzero(ev, sizeof(ngx_event_t);

    ev->data = data;
    ev->event_handler = ngx_http_cache_invalidate;

    return ngx_add_event(ev, NGX_VNODE_EVENT, 0);
}


void ngx_http_cache_invalidate(ngx_event_t *ev)
{
    ngx_http_cache_event_ctx_t  *ctx;

    ctx = ev->data;

    ngx_http_cache_lock(&ctx->hash->mutex);

    if (ctx->cache->refs == 0)
        ngx_http_cache_free(ctx->cache, NULL, NULL, ctx->log);

    } else {
        ctx->cache->deleted = 1;
    }

    ngx_http_cache_unlock(&ctx->hash->mutex);
}

#endif


/* TODO: currently fd only */

ngx_int_t ngx_http_send_cached(ngx_http_request_t *r)
{
    ngx_int_t            rc;
    ngx_hunk_t          *h;
    ngx_chain_t          out;
    ngx_http_log_ctx_t  *ctx;

    ctx = r->connection->log->data;
    ctx->action = "sending response to client";

    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = r->cache->data.size;
    r->headers_out.last_modified_time = r->cache->last_modified;

    if (ngx_http_set_content_type(r) != NGX_OK) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    /* we need to allocate all before the header would be sent */

    if (!(h = ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)))) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    if (!(h->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)))) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    rc = ngx_http_send_header(r);

    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        return rc;
    }

    h->type = r->main ? NGX_HUNK_FILE : NGX_HUNK_FILE|NGX_HUNK_LAST;

    h->file_pos = 0;
    h->file_last = r->cache->data.size;

    h->file->fd = r->cache->fd;
    h->file->log = r->connection->log;

    out.hunk = h;
    out.next = NULL;

    return ngx_http_output_filter(r, &out);
}


char *ngx_http_set_cache_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    char  *p = conf;

    ngx_int_t              i, j, dup, invalid;
    ngx_str_t              *value, line;
    ngx_http_cache_t       *c;
    ngx_http_cache_hash_t  *ch, **chp;

    chp = (ngx_http_cache_hash_t **) (p + cmd->offset);
    if (*chp) {
        return "is duplicate";
    }

    if (!(ch = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_hash_t)))) {
        return NGX_CONF_ERROR;
    }
    *chp = ch;

    dup = 0;
    invalid = 0;

    value = cf->args->elts;

    for (i = 1; i < cf->args->nelts; i++) {

        if (value[i].data[1] != '=') {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid value \"%s\"", value[i].data);
            return NGX_CONF_ERROR;
        }

        switch (value[i].data[0]) {

        case 'h':
            if (ch->hash) {
                dup = 1;
                break;
            }

            ch->hash = ngx_atoi(value[i].data + 2, value[i].len - 2);
            if (ch->hash == (size_t)  NGX_ERROR || ch->hash == 0) {
                invalid = 1;
                break;
            }

            continue;

        case 'n':
            if (ch->nelts) {
                dup = 1;
                break;
            }

            ch->nelts = ngx_atoi(value[i].data + 2, value[i].len - 2);
            if (ch->nelts == (size_t) NGX_ERROR || ch->nelts == 0) {
                invalid = 1;
                break;
            }

            continue;

        case 'l':
            if (ch->life) {
                dup = 1;
                break;
            }

            line.len = value[i].len - 2;
            line.data = value[i].data + 2;

            ch->life = ngx_parse_time(&line, 1);
            if (ch->life == NGX_ERROR || ch->life == 0) {
                invalid = 1;
                break;
            }

            continue;

        case 'u':
            if (ch->update) {
                dup = 1;
                break;
            }

            line.len = value[i].len - 2;
            line.data = value[i].data + 2;

            ch->update = ngx_parse_time(&line, 1);
            if (ch->update == NGX_ERROR || ch->update == 0) {
                invalid = 1;
                break;
            }

            continue;

        default:
            invalid = 1;
        }

        if (dup) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "duplicate value \"%s\"", value[i].data);
            return NGX_CONF_ERROR;
        }

        if (invalid) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "invalid value \"%s\"", value[i].data);
            return NGX_CONF_ERROR;
        }
    }

    ch->elts = ngx_pcalloc(cf->pool,
                           ch->hash * ch->nelts * sizeof(ngx_http_cache_t));
    if (ch->elts == NULL) {
        return NGX_CONF_ERROR;
    }

    for (i = 0; i < (ngx_int_t) ch->hash; i++) {
        c = ch->elts + i * ch->nelts;

        for (j = 0; j < (ngx_int_t) ch->nelts; j++) {
            c[j].fd = NGX_INVALID_FILE;
        }
    }

    return NGX_CONF_OK;
}


#endif
