/*
 * 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_namespace.h>
#include <axutil_string.h>
#include "axiom_namespace_internal.h"

struct axiom_namespace
{

    /** namespace URI */
    axutil_string_t *uri;

    /** namespace prefix  */
    axutil_string_t *prefix;

    axis2_char_t *key;

    int ref;
};

AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_namespace_create(
    const axutil_env_t * env,
    const axis2_char_t * uri,
    const axis2_char_t * prefix)
{
    axiom_namespace_t *om_namespace = NULL;

    if(!uri)
    {
        uri = "";
    }

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

    om_namespace->ref = 1;
    om_namespace->prefix = NULL;
    om_namespace->uri = NULL;
    om_namespace->key = NULL;

    om_namespace->uri = axutil_string_create(env, uri);
    if(!om_namespace->uri)
    {
        AXIS2_FREE(env->allocator, om_namespace);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    if(prefix)
    {
        om_namespace->prefix = axutil_string_create(env, prefix);
        if(!om_namespace->prefix)
        {
            AXIS2_FREE(env->allocator, om_namespace);
            AXIS2_FREE(env->allocator, om_namespace->uri);
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return NULL;
        }
    }

    return om_namespace;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_namespace_free(
    axiom_namespace_t * om_namespace,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    if(--om_namespace->ref > 0)
    {
        return;
    }

    if(om_namespace->prefix)
    {
        axutil_string_free(om_namespace->prefix, env);
    }

    if(om_namespace->uri)
    {
        axutil_string_free(om_namespace->uri, env);
    }

    if(om_namespace->key)
    {
        AXIS2_FREE(env->allocator, om_namespace->key);
    }

    AXIS2_FREE(env->allocator, om_namespace);
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axiom_namespace_equals(
    axiom_namespace_t * om_namespace,
    const axutil_env_t * env,
    axiom_namespace_t * om_namespace1)
{
    int uris_differ = 0;
    int prefixes_differ = 0;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_namespace, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_namespace1, AXIS2_FAILURE);

    if(!om_namespace || !om_namespace1)
    {
        return AXIS2_FALSE;
    }

    if(om_namespace->uri && om_namespace1->uri)
    {
        uris_differ = axutil_strcmp(axutil_string_get_buffer(om_namespace->uri, env),
            axutil_string_get_buffer(om_namespace1->uri, env));
    }
    else
    {
        uris_differ = (om_namespace->uri || om_namespace1->uri);
    }

    if(om_namespace->prefix && om_namespace1->prefix)
    {
        prefixes_differ = axutil_strcmp(axutil_string_get_buffer(om_namespace->prefix, env),
            axutil_string_get_buffer(om_namespace1->prefix, env));
    }
    else
    {
        prefixes_differ = (om_namespace->prefix || om_namespace1->prefix);
    }

    return (!uris_differ && !prefixes_differ);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_namespace_serialize(
    axiom_namespace_t * om_namespace,
    const axutil_env_t * env,
    axiom_output_t * om_output)
{
    int status = AXIS2_SUCCESS;
    if(!om_namespace)
    {
        return AXIS2_FAILURE;
    }

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

    if(om_namespace->uri && NULL != om_namespace->prefix && axutil_strcmp(axutil_string_get_buffer(
        om_namespace->prefix, env), "") != 0)
    {
        status = axiom_output_write(om_output, env, AXIOM_NAMESPACE, 2, axutil_string_get_buffer(
            om_namespace-> prefix, env), axutil_string_get_buffer(om_namespace->uri, env));
    }
    else if(om_namespace->uri)
    {
        status = axiom_output_write(om_output, env, AXIOM_NAMESPACE, 2, NULL,
            axutil_string_get_buffer(om_namespace->uri, env));
    }
    return status;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_namespace_get_uri(
    axiom_namespace_t * om_namespace,
    const axutil_env_t * env)
{
    if(om_namespace->uri)
    {
        return (axis2_char_t *)axutil_string_get_buffer(om_namespace->uri, env);
    }
    return NULL;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_namespace_get_prefix(
    axiom_namespace_t * om_namespace,
    const axutil_env_t * env)
{
    if(om_namespace->prefix)
    {
        return (axis2_char_t *)axutil_string_get_buffer(om_namespace->prefix, env);
    }
    return NULL;
}

AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_namespace_clone(
    axiom_namespace_t * om_namespace,
    const axutil_env_t * env)
{
    axiom_namespace_t *cloned_ns = NULL;

    AXIS2_ENV_CHECK(env, NULL);

    cloned_ns = axiom_namespace_create_str(env, om_namespace->uri, om_namespace->prefix);
    if(cloned_ns)
    {
        return cloned_ns;
    }
    return NULL;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_namespace_to_string(
    axiom_namespace_t * om_namespace,
    const axutil_env_t * env)
{
    axis2_char_t *temp_str = NULL;
    AXIS2_ENV_CHECK(env, NULL);
    if(om_namespace->key)
    {
        AXIS2_FREE(env->allocator, om_namespace->key);
        om_namespace->key = NULL;
    }
    if((om_namespace->uri) && (NULL != om_namespace->prefix))
    {
        temp_str = axutil_stracat(env, axutil_string_get_buffer(om_namespace->uri, env), "|");
        om_namespace->key = axutil_stracat(env, temp_str, axutil_string_get_buffer(
            om_namespace->prefix, env));
        if(temp_str)
        {
            AXIS2_FREE(env->allocator, temp_str);
            temp_str = NULL;
        }
    }
    else if((om_namespace->uri) && !(om_namespace->prefix))
    {
        om_namespace->key = axutil_strdup(env, axutil_string_get_buffer(om_namespace->uri, env));
        if(!(om_namespace->key))
        {
            return NULL;
        }
    }
    return om_namespace->key;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_namespace_set_uri(
    axiom_namespace_t * om_namespace,
    const axutil_env_t * env,
    const axis2_char_t * uri)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE);

    if(om_namespace->uri)
    {
        axutil_string_free(om_namespace->uri, env);
        om_namespace->uri = NULL;
    }

    om_namespace->uri = axutil_string_create(env, uri);
    if(!(om_namespace->uri))
    {
        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_namespace_increment_ref(
    struct axiom_namespace * om_namespace,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    om_namespace->ref++;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axiom_namespace_t *AXIS2_CALL
axiom_namespace_create_str(
    const axutil_env_t * env,
    axutil_string_t * uri,
    axutil_string_t * prefix)
{
    axiom_namespace_t *om_namespace = NULL;

    if(!uri)
    {
        uri = axutil_string_create(env, "");
    }

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

    om_namespace->ref = 0;
    om_namespace->prefix = NULL;
    om_namespace->uri = NULL;
    om_namespace->key = NULL;

    om_namespace->uri = axutil_string_clone(uri, env);
    if(!om_namespace->uri)
    {
        AXIS2_FREE(env->allocator, om_namespace);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    if(prefix)
    {
        om_namespace->prefix = axutil_string_clone(prefix, env);
        if(!om_namespace->prefix)
        {
            AXIS2_FREE(env->allocator, om_namespace);
            AXIS2_FREE(env->allocator, om_namespace->uri);
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return NULL;
        }
    }

    return om_namespace;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_namespace_set_uri_str(
    axiom_namespace_t * om_namespace,
    const axutil_env_t * env,
    axutil_string_t * uri)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, uri, AXIS2_FAILURE);

    if(om_namespace->uri)
    {
        axutil_string_free(om_namespace->uri, env);
        om_namespace->uri = NULL;
    }

    om_namespace->uri = axutil_string_clone(uri, env);
    if(!(om_namespace->uri))
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }

    return AXIS2_SUCCESS;

}

AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axiom_namespace_get_uri_str(
    axiom_namespace_t * om_namespace,
    const axutil_env_t * env)
{
    return om_namespace->uri;
}

AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axiom_namespace_get_prefix_str(
    axiom_namespace_t * om_namespace,
    const axutil_env_t * env)
{
    return om_namespace->prefix;
}
