/*
 * 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 <axutil_param.h>
#include <axutil_utils.h>
#include <axutil_string.h>
#include <axutil_generic_obj.h>

struct axutil_param
{
    /** Parameter name */
    axis2_char_t *name;

    /** Parameter value */
    void *value;

    /** Parameter locked? */
    axis2_bool_t locked;

    /** Parameter type */
    int type;                   /*default is AXIS2_TEXT_PARAM */
    axutil_hash_t *attrs;
    axutil_array_list_t *value_list;
     void(
    AXIS2_CALL *value_free) (
    void *param_value,
    const axutil_env_t *env);
};

AXIS2_EXTERN axutil_param_t *AXIS2_CALL
axutil_param_create(
    const axutil_env_t *env,
    axis2_char_t *name,
    void *value)
{
    axutil_param_t *param = NULL;
    AXIS2_ENV_CHECK(env, NULL);

    param = AXIS2_MALLOC(env->allocator, sizeof(axutil_param_t));
    if(!param)
    {
        AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Not enough memory");
        AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE);
        return NULL;
    }

    param->name = axutil_strdup(env, name);
    param->value = value; /* shallow copy. */
    param->locked = AXIS2_FALSE;
    param->type = AXIS2_TEXT_PARAM;
    param->attrs = NULL;
    param->value_list = NULL;
    param->value_free = NULL;

    return param;
}

axis2_char_t *AXIS2_CALL
axutil_param_get_name(
    axutil_param_t *param,
    const axutil_env_t *env)
{
    return param->name;
}

void *AXIS2_CALL
axutil_param_get_value(
    axutil_param_t *param,
    const axutil_env_t *env)
{
    return param->value;
}

axis2_status_t AXIS2_CALL
axutil_param_set_name(
    axutil_param_t *param,
    const axutil_env_t *env,
    const axis2_char_t *name)
{
    param->name = axutil_strdup(env, name);
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axutil_param_set_value(
    axutil_param_t *param,
    const axutil_env_t *env,
    const void *value)
{
    void *param_value = NULL;
    param_value = axutil_param_get_value(param, env);
    if(param_value)
    {
        if(param && param->value_free)
        {
            param->value_free(param_value, env);
        }
        else /* we assume that param value is axis2_char_t* */
        {
            AXIS2_FREE(env->allocator, param_value);
        }
    }
    param->value = (void *)value;
    return AXIS2_SUCCESS;
}

axis2_bool_t AXIS2_CALL
axutil_param_is_locked(
    axutil_param_t *param,
    const axutil_env_t *env)
{
    return param->locked;
}

axis2_status_t AXIS2_CALL
axutil_param_set_locked(
    axutil_param_t *param,
    const axutil_env_t *env,
    axis2_bool_t value)
{
    param->locked = value;
    return AXIS2_SUCCESS;
}

int AXIS2_CALL
axutil_param_get_param_type(
    axutil_param_t *param,
    const axutil_env_t *env)
{
    return param->type;
}

axis2_status_t AXIS2_CALL
axutil_param_set_param_type(
    axutil_param_t *param,
    const axutil_env_t *env,
    int type)
{
    param->type = type;
    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axutil_param_set_attributes(
    axutil_param_t *param,
    const axutil_env_t *env,
    axutil_hash_t *attrs)
{
    AXIS2_PARAM_CHECK(env->error, attrs, AXIS2_FAILURE);

    if(param->attrs)
    {
        axutil_hash_index_t *i = NULL;
        void *v = NULL;

        for(i = axutil_hash_first(param->attrs, env); i; i = axutil_hash_next(env, i))
        {
            axutil_hash_this(i, NULL, NULL, &v);
            axutil_generic_obj_free(v, env);
        }
        axutil_hash_free(param->attrs, env);
    }

    param->attrs = attrs;
    return AXIS2_SUCCESS;
}

axutil_hash_t *AXIS2_CALL
axutil_param_get_attributes(
    axutil_param_t *param,
    const axutil_env_t *env)
{
    return param->attrs;
}

axis2_status_t AXIS2_CALL
axutil_param_set_value_list(
    axutil_param_t *param,
    const axutil_env_t *env,
    axutil_array_list_t *value_list)
{
    AXIS2_PARAM_CHECK(env->error, value_list, AXIS2_FAILURE);

    if(param->value_list)
    {
        int i = 0, size = 0;

        size = axutil_array_list_size(param->value_list, env);
        for(i = 0; i < size; i++)
        {
            axutil_param_t *param = NULL;

            param = (axutil_param_t *)axutil_array_list_get(param->value_list, env, i);
            axutil_param_free(param, env);
        }
        axutil_array_list_free(param->value_list, env);
    }
    param->value_list = value_list;

    return AXIS2_SUCCESS;
}

axutil_array_list_t *AXIS2_CALL
axutil_param_get_value_list(
    axutil_param_t *param,
    const axutil_env_t *env)
{
    return param->value_list;
}

void AXIS2_CALL
axutil_param_free(
    axutil_param_t *param,
    const axutil_env_t *env)
{
    void *param_value = NULL;
    axis2_char_t *param_name = NULL;

    param_value = axutil_param_get_value(param, env);
    if(param_value)
    {
        if(param && param->value_free)
        {
            param->value_free(param_value, env);
        }
        else /* we assume that param value is axis2_char_t* */
        {
            AXIS2_FREE(env->allocator, param_value);
        }
    }

    if(param->attrs)
    {
        axutil_hash_index_t *i = NULL;
        void *v = NULL;

        for(i = axutil_hash_first(param->attrs, env); i; i = axutil_hash_next(env, i))
        {
            axutil_hash_this(i, NULL, NULL, &v);
            axutil_generic_obj_free(v, env);
        }
        axutil_hash_free(param->attrs, env);
    }

    if(param->value_list)
    {
        int i = 0, size = 0;

        size = axutil_array_list_size(param->value_list, env);
        for(i = 0; i < size; i++)
        {
            axutil_param_t *param_l = NULL;

            param_l = (axutil_param_t *)axutil_array_list_get(param->value_list, env, i);
            if(param_l)
            {
                axutil_param_free(param_l, env);
            }
        }
        axutil_array_list_free(param->value_list, env);
    }
    param_name = axutil_param_get_name(param, env);
    AXIS2_FREE(env->allocator, param_name);
    AXIS2_FREE(env->allocator, param);
    return;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_param_set_value_free(
    axutil_param_t *param,
    const axutil_env_t *env,
    AXIS2_PARAM_VALUE_FREE free_fn)
{
    param->value_free = free_fn;
    return AXIS2_SUCCESS;
}

/* Use this function for the copied parameters
 * to avoid double free
 */
AXIS2_EXTERN void AXIS2_CALL
axutil_param_dummy_free_fn(
    void *param,
    const axutil_env_t *env)
{
    return;
}
