
/*
 * 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 <axis2_svc_grp_ctx.h>
#include <axis2_svc_grp.h>
#include <axis2_const.h>
#include <axutil_hash.h>

struct axis2_svc_grp_ctx
{

    /** base context struct */
    axis2_ctx_t *base;

    /** parent of service group context is a configuration context instance */
    struct axis2_conf_ctx *parent;

    /** service group context ID */
    axis2_char_t *id;

    /** map of service contexts belonging to this service context group */
    axutil_hash_t *svc_ctx_map;

    /** service group associated with this service group context */
    axis2_svc_grp_t *svc_grp;

    /** name of the service group associated with this context */
    axis2_char_t *svc_grp_name;
};

AXIS2_EXTERN axis2_svc_grp_ctx_t *AXIS2_CALL
axis2_svc_grp_ctx_create(
    const axutil_env_t * env,
    axis2_svc_grp_t * svc_grp,
    struct axis2_conf_ctx *conf_ctx)
{
    axis2_svc_grp_ctx_t *svc_grp_ctx = NULL;

    svc_grp_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_grp_ctx_t));
    if (!svc_grp_ctx)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    svc_grp_ctx->base = NULL;
    svc_grp_ctx->parent = NULL;
    svc_grp_ctx->id = NULL;
    svc_grp_ctx->svc_ctx_map = NULL;
    svc_grp_ctx->svc_grp = NULL;
    svc_grp_ctx->svc_grp_name = NULL;

    svc_grp_ctx->base = axis2_ctx_create(env);
    if (!(svc_grp_ctx->base))
    {
        axis2_svc_grp_ctx_free(svc_grp_ctx, env);
        return NULL;
    }

    if (svc_grp)
    {
        svc_grp_ctx->svc_grp = svc_grp;
        svc_grp_ctx->svc_grp_name =
            (axis2_char_t *) axis2_svc_grp_get_name(svc_grp_ctx->svc_grp, env);
        svc_grp_ctx->id = axutil_strdup(env, svc_grp_ctx->svc_grp_name);
    }

    if (conf_ctx)
    {
        svc_grp_ctx->parent = conf_ctx;
    }

    svc_grp_ctx->svc_ctx_map = axutil_hash_make(env);
    if (!(svc_grp_ctx->svc_ctx_map))
    {
        axis2_svc_grp_ctx_free(svc_grp_ctx, env);
        return NULL;
    }

    axis2_svc_grp_ctx_fill_svc_ctx_map((svc_grp_ctx), env);

    return svc_grp_ctx;
}

AXIS2_EXTERN axis2_ctx_t *AXIS2_CALL
axis2_svc_grp_ctx_get_base(
    const axis2_svc_grp_ctx_t * svc_grp_ctx,
    const axutil_env_t * env)
{
    return svc_grp_ctx->base;
}

AXIS2_EXTERN struct axis2_conf_ctx *AXIS2_CALL
axis2_svc_grp_ctx_get_parent(
    const axis2_svc_grp_ctx_t * svc_grp_ctx,
    const axutil_env_t * env)
{
    return svc_grp_ctx->parent;
}

AXIS2_EXTERN void AXIS2_CALL
axis2_svc_grp_ctx_free(
    struct axis2_svc_grp_ctx *svc_grp_ctx,
    const axutil_env_t * env)
{
    if (svc_grp_ctx->id)
    {
        AXIS2_FREE(env->allocator, svc_grp_ctx->id);
    }

    if (svc_grp_ctx->base)
    {
        axis2_ctx_free(svc_grp_ctx->base, env);
    }

    if (svc_grp_ctx->svc_ctx_map)
    {
        axutil_hash_index_t *hi = NULL;
        void *val = NULL;
        for (hi = axutil_hash_first(svc_grp_ctx->svc_ctx_map, env);
             hi; hi = axutil_hash_next(env, hi))
        {
            axutil_hash_this(hi, NULL, NULL, &val);
            if (val)
            {
                axis2_svc_ctx_t *svc_ctx = NULL;
                svc_ctx = (axis2_svc_ctx_t *) val;
                axis2_svc_ctx_free(svc_ctx, env);
            }
        }

        axutil_hash_free(svc_grp_ctx->svc_ctx_map, env);
        svc_grp_ctx->base = NULL;
    }

    AXIS2_FREE(env->allocator, svc_grp_ctx);

    return;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_grp_ctx_init(
    struct axis2_svc_grp_ctx * svc_grp_ctx,
    const axutil_env_t * env,
    axis2_conf_t * conf)
{
    if (svc_grp_ctx->svc_grp_name)
    {
        svc_grp_ctx->svc_grp =
            axis2_conf_get_svc_grp(conf, env, svc_grp_ctx->svc_grp_name);
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
axis2_svc_grp_ctx_get_id(
    const axis2_svc_grp_ctx_t * svc_grp_ctx,
    const axutil_env_t * env)
{
    return svc_grp_ctx->id;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_grp_ctx_set_id(
    struct axis2_svc_grp_ctx * svc_grp_ctx,
    const axutil_env_t * env,
    const axis2_char_t * id)
{
    if (svc_grp_ctx->id)
    {
        AXIS2_FREE(env->allocator, svc_grp_ctx->id);
        svc_grp_ctx->id = NULL;
    }

    if (id)
    {
        svc_grp_ctx->id = axutil_strdup(env, id);
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_svc_ctx_t *AXIS2_CALL
axis2_svc_grp_ctx_get_svc_ctx(
    const axis2_svc_grp_ctx_t * svc_grp_ctx,
    const axutil_env_t * env,
    const axis2_char_t * svc_name)
{
    return (axis2_svc_ctx_t *) axutil_hash_get(svc_grp_ctx->svc_ctx_map,
                                               svc_name, AXIS2_HASH_KEY_STRING);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_svc_grp_ctx_fill_svc_ctx_map(
    struct axis2_svc_grp_ctx * svc_grp_ctx,
    const axutil_env_t * env)
{
    axutil_hash_index_t *hi = NULL;
    void *next_svc = NULL;

    if (svc_grp_ctx->svc_grp)
    {
        axutil_hash_t *service_map =
            axis2_svc_grp_get_all_svcs(svc_grp_ctx->svc_grp, env);
        if (service_map)
        {
            for (hi = axutil_hash_first(service_map, env);
                 hi; hi = axutil_hash_next(env, hi))
            {
                axutil_hash_this(hi, NULL, NULL, &next_svc);
                if (next_svc)
                {
                    axis2_svc_t *svc = NULL;
                    axis2_svc_ctx_t *svc_ctx = NULL;
                    axis2_char_t *svc_name = NULL;
                    svc = (axis2_svc_t *) next_svc;
                    svc_ctx = axis2_svc_ctx_create(env, svc, svc_grp_ctx);
                    svc_name =
                        axutil_qname_get_localpart(axis2_svc_get_qname
                                                   (svc, env), env);
                    if (svc_name)
                        axutil_hash_set(svc_grp_ctx->svc_ctx_map, svc_name,
                                        AXIS2_HASH_KEY_STRING, svc_ctx);
                }
            }
        }
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_svc_grp_t *AXIS2_CALL
axis2_svc_grp_ctx_get_svc_grp(
    const axis2_svc_grp_ctx_t * svc_grp_ctx,
    const axutil_env_t * env)
{
    return svc_grp_ctx->svc_grp;
}

AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axis2_svc_grp_ctx_get_svc_ctx_map(
    const axis2_svc_grp_ctx_t * svc_grp_ctx,
    const axutil_env_t * env)
{
    return svc_grp_ctx->svc_ctx_map;
}

