/*
 * 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 <axiom_attribute.h>
#include <string.h>
#include <axutil_utils_defines.h>

struct axiom_attribute
{

    /** localname of this attribute  */
    axutil_string_t *localname;

    /** value of this attribute */
    axutil_string_t *value;

    /** attribute namespace */
    axiom_namespace_t *ns;

    /** store qname here */
    axutil_qname_t *qname;
    int ref;
};

AXIS2_EXTERN axiom_attribute_t *AXIS2_CALL
axiom_attribute_create(
    const axutil_env_t * env,
    const axis2_char_t * localname,
    const axis2_char_t * value,
    axiom_namespace_t * ns)
{
    axiom_attribute_t *attribute = NULL;

    AXIS2_ENV_CHECK(env, NULL);
    /* localname is mandatory */
    AXIS2_PARAM_CHECK(env->error, localname, NULL);

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

    /**  initialize fields */
    attribute->localname = NULL;
    attribute->value = NULL;
    attribute->ns = NULL;
    attribute->qname = NULL;

    attribute->localname = axutil_string_create(env, localname);
    if(!(attribute->localname))
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_FREE(env->allocator, attribute);
        return NULL;
    }
    if(value)
    {
        attribute->value = axutil_string_create(env, value);
        if(!(attribute->value))
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            axutil_string_free(attribute->localname, env);
            AXIS2_FREE(env->allocator, attribute);
            return NULL;
        }
    }
    attribute->ns = ns;

    attribute->ref = 0;

    return attribute;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_attribute_free(
    axiom_attribute_t * attribute,
    const axutil_env_t * env)
{
    if(--attribute->ref > 0)
    {
        return;
    }

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    if(attribute->localname)
    {
        axutil_string_free(attribute->localname, env);
    }
    if(attribute->value)
    {
        axutil_string_free(attribute->value, env);
    }
    if(attribute->qname)
    {
        axutil_qname_free(attribute->qname, env);
    }

    AXIS2_FREE(env->allocator, attribute);

    return;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_attribute_free_void_arg(
    void *attribute,
    const axutil_env_t * env)
{
    axiom_attribute_t *om_attribute_l = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    om_attribute_l = (axiom_attribute_t *)attribute;
    axiom_attribute_free(om_attribute_l, env);
    return;
}

AXIS2_EXTERN axutil_qname_t *AXIS2_CALL
axiom_attribute_get_qname(
    axiom_attribute_t * attribute,
    const axutil_env_t * env)
{
    axutil_qname_t *qname = NULL;
    AXIS2_ENV_CHECK(env, NULL);
    if(!(attribute->qname))
    {
        if(attribute->ns)
        {
            qname = axutil_qname_create(env, axutil_string_get_buffer(attribute-> localname, env),
                axiom_namespace_get_uri(attribute->ns, env), axiom_namespace_get_prefix(
                    attribute-> ns, env));
        }
        else
        {
            qname = axutil_qname_create(env, axutil_string_get_buffer(attribute-> localname, env),
                NULL, NULL);
        }
        attribute->qname = qname;
        return qname;
    }
    return attribute->qname;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_attribute_serialize(
    axiom_attribute_t * attribute,
    const axutil_env_t * env,
    axiom_output_t * om_output)
{
    int status = AXIS2_SUCCESS;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE);

    if(attribute->ns)
    {
        axis2_char_t *uri = NULL;
        axis2_char_t *prefix = NULL;

        uri = axiom_namespace_get_uri(attribute->ns, env);
        prefix = axiom_namespace_get_prefix(attribute->ns, env);

        if((uri) && (NULL != prefix) && (axutil_strcmp(prefix, "") != 0))
        {
            status = axiom_output_write(om_output, env, AXIOM_ATTRIBUTE, 4,
                axutil_string_get_buffer(attribute-> localname, env), axutil_string_get_buffer(
                    attribute-> value, env), uri, prefix);
        }
        else if(uri)
        {
            status = axiom_output_write(om_output, env, AXIOM_ATTRIBUTE, 3,
                axutil_string_get_buffer(attribute-> localname, env), axutil_string_get_buffer(
                    attribute-> value, env), uri);
        }
    }
    else
    {
        status = axiom_output_write(om_output, env, AXIOM_ATTRIBUTE, 2, axutil_string_get_buffer(
            attribute-> localname, env), axutil_string_get_buffer(attribute->value, env));
    }
    return status;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_attribute_get_localname(
    axiom_attribute_t * attribute,
    const axutil_env_t * env)
{
    AXIS2_ASSERT(attribute);
    AXIS2_ASSERT(attribute->localname);
    return (axis2_char_t *)axutil_string_get_buffer(attribute->localname, env);
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_attribute_get_value(
    axiom_attribute_t * attribute,
    const axutil_env_t * env)
{
    if(attribute->value)
    {
        return (axis2_char_t *)axutil_string_get_buffer(attribute->value, env);
    }
    return NULL;
}

AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_attribute_get_namespace(
    axiom_attribute_t * attribute,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, NULL);
    return attribute->ns;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_attribute_set_localname(
    axiom_attribute_t * attribute,
    const axutil_env_t * env,
    const axis2_char_t * localname)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE);

    if(attribute->localname)
    {
        axutil_string_free(attribute->localname, env);
        attribute->localname = NULL;
    }

    attribute->localname = axutil_string_create(env, localname);

    if(!(attribute->localname))
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_attribute_set_value(
    axiom_attribute_t * attribute,
    const axutil_env_t * env,
    const axis2_char_t * value)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE);

    if(attribute->value)
    {
        axutil_string_free(attribute->value, env);
        attribute->value = NULL;
    }

    attribute->value = axutil_string_create(env, value);
    if(!(attribute->value))
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_attribute_set_namespace(
    axiom_attribute_t * attribute,
    const axutil_env_t * env,
    axiom_namespace_t * om_namespace)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_FUNC_PARAM_CHECK(om_namespace, env, AXIS2_FAILURE);
    attribute->ns = om_namespace;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axiom_attribute_t *AXIS2_CALL
axiom_attribute_clone(
    axiom_attribute_t * attribute,
    const axutil_env_t * env)
{
    axiom_attribute_t *cloned_attr = NULL;
    if(!attribute)
        return NULL;
    AXIS2_ENV_CHECK(env, NULL);

    /** namespace is not cloned since it is a shollow copy*/
    cloned_attr = axiom_attribute_create_str(env, attribute->localname, attribute->value,
        attribute->ns);
    if(cloned_attr)
    {
        return cloned_attr;
    }
    return NULL;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_attribute_increment_ref(
    struct axiom_attribute * om_attribute,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    om_attribute->ref++;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axiom_attribute_t *AXIS2_CALL
axiom_attribute_create_str(
    const axutil_env_t * env,
    axutil_string_t * localname,
    axutil_string_t * value,
    axiom_namespace_t * ns)
{
    axiom_attribute_t *attribute = NULL;

    AXIS2_ENV_CHECK(env, NULL);
    /* localname is mandatory */
    AXIS2_PARAM_CHECK(env->error, localname, NULL);

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

    /**  initialize fields */
    attribute->localname = NULL;
    attribute->value = NULL;
    attribute->ns = NULL;
    attribute->qname = NULL;

    attribute->localname = axutil_string_clone(localname, env);
    if(!(attribute->localname))
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_FREE(env->allocator, attribute);
        return NULL;
    }
    if(value)
    {
        attribute->value = axutil_string_clone(value, env);
        if(!(attribute->value))
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            axutil_string_free(attribute->localname, env);
            AXIS2_FREE(env->allocator, attribute);
            return NULL;
        }
    }
    attribute->ns = ns;

    attribute->ref = 0;

    return attribute;
}

AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axiom_attribute_get_localname_str(
    axiom_attribute_t * attribute,
    const axutil_env_t * env)
{
    return attribute->localname;
}

AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axiom_attribute_get_value_str(
    axiom_attribute_t * attribute,
    const axutil_env_t * env)
{
    return attribute->value;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_attribute_set_localname_str(
    axiom_attribute_t * attribute,
    const axutil_env_t * env,
    axutil_string_t * localname)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, localname, AXIS2_FAILURE);

    if(attribute->localname)
    {
        axutil_string_free(attribute->localname, env);
        attribute->localname = NULL;
    }

    attribute->localname = axutil_string_clone(localname, env);

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_attribute_set_value_str(
    axiom_attribute_t * attribute,
    const axutil_env_t * env,
    axutil_string_t * value)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE);

    if(attribute->value)
    {
        axutil_string_free(attribute->value, env);
        attribute->value = NULL;
    }

    attribute->value = axutil_string_clone(value, env);
    if(!(attribute->value))
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}
