/*
 *  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.
 */

/***************************************************************************
 * Description: Context handling (Autoconf)                                *
 * Author:      Henri Gomez <hgomez@apache.org>                            *
 * Version:     $Revision$                                           *
 ***************************************************************************/

#include "jk_global.h"
#include "jk_context.h"
#include "jk_ajp_common.h"


/*
 * Set the virtual name of the context 
 */

int context_set_virtual(jk_context_t *c, char *virt)
{
    if (c) {

        if (virt) {
            c->virt = jk_pool_strdup(&c->p, virt);

            if (!c->virt)
                return JK_FALSE;
        }

        return JK_TRUE;
    }

    return JK_FALSE;
}

/*
 * Init the context info struct
 */

int context_open(jk_context_t *c, char *virt)
{
    if (c) {
        jk_open_pool(&c->p, c->buf, sizeof(jk_pool_atom_t) * SMALL_POOL_SIZE);
        c->size = 0;
        c->capacity = 0;
        c->contexts = NULL;

        return context_set_virtual(c, virt);
    }

    return JK_FALSE;
}

/*
 * Close the context info struct
 */

int context_close(jk_context_t *c)
{
    if (c) {

        jk_close_pool(&c->p);
        return JK_TRUE;
    }

    return JK_FALSE;
}

/*
 * Allocate and open context
 */

int context_alloc(jk_context_t **c, char *virt)
{
    if (c)
        return context_open(*c =
                            (jk_context_t *)calloc(1, sizeof(jk_context_t)),
                            virt);

    return JK_FALSE;
}

/*
 * Close and destroy context
 */

int context_free(jk_context_t **c)
{
    if (c && *c) {
        context_close(*c);
        free(*c);
        *c = NULL;
        return JK_TRUE;
    }

    return JK_FALSE;
}


/*
 * Ensure there will be memory in context info to store Context Bases
 */

static int context_realloc(jk_context_t *c)
{
    if (c->size == c->capacity) {
        jk_context_item_t **contexts;
        int capacity = c->capacity + CBASE_INC_SIZE;

        contexts =
            (jk_context_item_t **)jk_pool_alloc(&c->p,
                                                sizeof(jk_context_item_t *) *
                                                capacity);

        if (!contexts)
            return JK_FALSE;

        if (c->capacity && c->contexts)
            memcpy(contexts, c->contexts,
                   sizeof(jk_context_item_t *) * c->capacity);

        c->contexts = contexts;
        c->capacity = capacity;
    }

    return JK_TRUE;
}

/*
 * Ensure there will be memory in context info to URIS
 */

static int context_item_realloc(jk_context_t *c, jk_context_item_t *ci)
{
    if (ci->size == ci->capacity) {
        char **uris;
        int capacity = ci->capacity + URI_INC_SIZE;

        uris = (char **)jk_pool_alloc(&c->p, sizeof(char *) * capacity);

        if (!uris)
            return JK_FALSE;

        memcpy(uris, ci->uris, sizeof(char *) * ci->capacity);

        ci->uris = uris;
        ci->capacity = capacity;
    }

    return JK_TRUE;
}


/*
 * Locate a context base in context list
 */

jk_context_item_t *context_find_base(jk_context_t *c, char *cbase)
{
    int i;
    jk_context_item_t *ci;

    if (!c || !cbase)
        return NULL;

    for (i = 0; i < c->size; i++) {

        ci = c->contexts[i];

        if (!ci)
            continue;

        if (!strcmp(ci->cbase, cbase))
            return ci;
    }

    return NULL;
}

/*
 * Locate an URI in a context item
 */

char *context_item_find_uri(jk_context_item_t *ci, char *uri)
{
    int i;

    if (!ci || !uri)
        return NULL;

    for (i = 0; i < ci->size; i++) {
        if (!strcmp(ci->uris[i], uri))
            return ci->uris[i];
    }

    return NULL;
}

void context_dump_uris(jk_context_t *c, char *cbase, FILE * f)
{
    jk_context_item_t *ci;
    int i;

    ci = context_find_base(c, cbase);

    if (!ci)
        return;

    for (i = 0; i < ci->size; i++)
        fprintf(f, "/%s/%s\n", ci->cbase, ci->uris[i]);

    fflush(f);
}


/*
 * Add a new context item to context
 */

jk_context_item_t *context_add_base(jk_context_t *c, char *cbase)
{
    jk_context_item_t *ci;

    if (!c || !cbase)
        return NULL;

    /* Check if the context base was not allready created */
    ci = context_find_base(c, cbase);

    if (ci)
        return ci;

    if (context_realloc(c) != JK_TRUE)
        return NULL;

    ci = (jk_context_item_t *)jk_pool_alloc(&c->p, sizeof(jk_context_item_t));

    if (!ci)
        return NULL;

    c->contexts[c->size] = ci;
    c->size++;
    ci->cbase = jk_pool_strdup(&c->p, cbase);
    ci->status = 0;
    ci->size = 0;
    ci->capacity = 0;
    ci->uris = NULL;

    return ci;
}

/*
 * Add a new URI to a context item
 */

int context_add_uri(jk_context_t *c, char *cbase, char *uri)
{
    jk_context_item_t *ci;

    if (!uri)
        return JK_FALSE;

    /* Get/Create the context base */
    ci = context_add_base(c, cbase);

    if (!ci)
        return JK_FALSE;

    if (context_item_find_uri(ci, uri) != NULL)
        return JK_TRUE;

    if (context_item_realloc(c, ci) == JK_FALSE)
        return JK_FALSE;

    ci->uris[ci->size] = jk_pool_strdup(&c->p, uri);

    if (ci->uris[ci->size] == NULL)
        return JK_FALSE;

    ci->size++;
    return JK_TRUE;
}
