
/*
 * 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_endpoint_ref.h>
#include <axutil_string.h>
#include <axutil_array_list.h>

struct axis2_endpoint_ref
{

    /** endpoint address */
    axis2_char_t *address;

    /** interface qname */
    axutil_qname_t *interface_qname;

    /** reference parameters */
    axutil_array_list_t *ref_param_list;

    /** meta data */
    axutil_array_list_t *metadata_list;

    /** reference parameter attribute list */
    axutil_array_list_t *ref_attribute_list;

    /** meta data attribute list */
    axutil_array_list_t *meta_attribute_list;

    /** extensible element list */
    axutil_array_list_t *extension_list;

    /** service name */
    axis2_svc_name_t *svc_name;
};

axis2_endpoint_ref_t *AXIS2_CALL
axis2_endpoint_ref_create(
    const axutil_env_t * env,
    const axis2_char_t * address)
{
    axis2_endpoint_ref_t *endpoint_ref = NULL;

    AXIS2_ENV_CHECK(env, NULL);

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

    endpoint_ref->address = NULL;
    endpoint_ref->interface_qname = NULL;
    endpoint_ref->ref_param_list = NULL;
    endpoint_ref->metadata_list = NULL;
    endpoint_ref->ref_attribute_list = NULL;
    endpoint_ref->meta_attribute_list = NULL;
    endpoint_ref->extension_list = NULL;
    endpoint_ref->svc_name = NULL;

    if (address)
    {
        endpoint_ref->address = axutil_strdup(env, address);
        if (!(endpoint_ref->address))
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            axis2_endpoint_ref_free(endpoint_ref, env);
            return NULL;
        }
    }

    return endpoint_ref;
}

const axis2_char_t *AXIS2_CALL
axis2_endpoint_ref_get_address(
    const axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env)
{
    return endpoint_ref->address;
}

axis2_status_t AXIS2_CALL
axis2_endpoint_ref_set_address(
    axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env,
    const axis2_char_t * address)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    if (endpoint_ref->address)
    {
        AXIS2_FREE(env->allocator, endpoint_ref->address);
    }

    endpoint_ref->address = axutil_strdup(env, address);
    return AXIS2_SUCCESS;
}

const axutil_qname_t *AXIS2_CALL
axis2_endpoint_ref_get_interface_qname(
    const axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env)
{
    return endpoint_ref->interface_qname;
}

axis2_status_t AXIS2_CALL
axis2_endpoint_ref_set_interface_qname(
    axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env,
    const axutil_qname_t * interface_qname)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    endpoint_ref->interface_qname =
        axutil_qname_clone((axutil_qname_t *) interface_qname, env);
    return AXIS2_SUCCESS;
}

axis2_svc_name_t *AXIS2_CALL
axis2_endpoint_ref_get_svc_name(
    const axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env)
{
    return endpoint_ref->svc_name;
}

axis2_status_t AXIS2_CALL
axis2_endpoint_ref_set_svc_name(
    axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env,
    axis2_svc_name_t * svc_name)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    endpoint_ref->svc_name = svc_name;
    return AXIS2_SUCCESS;
}

void AXIS2_CALL
axis2_endpoint_ref_free_void_arg(
    void *endpoint_ref,
    const axutil_env_t * env)
{
    axis2_endpoint_ref_t *endpoint_ref_l = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    endpoint_ref_l = (axis2_endpoint_ref_t *) endpoint_ref;
    axis2_endpoint_ref_free(endpoint_ref_l, env);
    return;
}

void AXIS2_CALL
axis2_endpoint_ref_free(
    axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, void);

    if (endpoint_ref->address)
    {
        AXIS2_FREE(env->allocator, endpoint_ref->address);
    }

    if (endpoint_ref->ref_param_list)
    {
        axutil_array_list_free(endpoint_ref->ref_param_list, env);
    }

    if (endpoint_ref->metadata_list)
    {
        axutil_array_list_free(endpoint_ref->metadata_list, env);
    }

    if (endpoint_ref->ref_attribute_list)
    {
        axutil_array_list_free(endpoint_ref->ref_attribute_list, env);
    }

    if (endpoint_ref->meta_attribute_list)
    {
        axutil_array_list_free(endpoint_ref->meta_attribute_list, env);
    }

    if (endpoint_ref->extension_list)
    {
        axutil_array_list_free(endpoint_ref->extension_list, env);
    }

    AXIS2_FREE(env->allocator, endpoint_ref);

    return;
}

axutil_array_list_t *AXIS2_CALL
axis2_endpoint_ref_get_ref_param_list(
    const axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env)
{
    return endpoint_ref->ref_param_list;
}

axutil_array_list_t *AXIS2_CALL
axis2_endpoint_ref_get_metadata_list(
    const axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env)
{
    return endpoint_ref->metadata_list;
}

axis2_status_t AXIS2_CALL
axis2_endpoint_ref_add_ref_param(
    axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env,
    axiom_node_t * ref_param_node)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    if (!(endpoint_ref->ref_param_list))
    {
        endpoint_ref->ref_param_list = axutil_array_list_create(env, 0);
        if (!(endpoint_ref->ref_param_list))
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }
    }

    if (endpoint_ref->ref_param_list && ref_param_node)
    {
        return axutil_array_list_add(endpoint_ref->ref_param_list, env,
                                     ref_param_node);
    }

    return AXIS2_FAILURE;
}

axis2_status_t AXIS2_CALL
axis2_endpoint_ref_add_metadata(
    axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env,
    axiom_node_t * meta_data_node)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    if (!(endpoint_ref->metadata_list))
    {
        endpoint_ref->metadata_list = axutil_array_list_create(env, 0);
        if (!(endpoint_ref->metadata_list))
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }
    }

    if (endpoint_ref->metadata_list && meta_data_node)
    {
        return axutil_array_list_add(endpoint_ref->metadata_list, env,
                                     meta_data_node);
    }

    return AXIS2_FAILURE;
}

axutil_array_list_t *AXIS2_CALL
axis2_endpoint_ref_get_ref_attribute_list(
    const axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env)
{
    return endpoint_ref->ref_attribute_list;
}

axutil_array_list_t *AXIS2_CALL
axis2_endpoint_ref_get_metadata_attribute_list(
    const axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env)
{
    return endpoint_ref->meta_attribute_list;
}

axutil_array_list_t *AXIS2_CALL
axis2_endpoint_ref_get_extension_list(
    const axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env)
{
    return endpoint_ref->extension_list;
}

axis2_status_t AXIS2_CALL
axis2_endpoint_ref_add_ref_attribute(
    axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env,
    axiom_attribute_t * attr)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    if (!(endpoint_ref->ref_attribute_list))
    {
        endpoint_ref->ref_attribute_list = axutil_array_list_create(env, 0);
        if (!(endpoint_ref->ref_attribute_list))
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }
    }

    if (endpoint_ref->ref_attribute_list && attr)
    {
        return axutil_array_list_add(endpoint_ref->ref_attribute_list, env,
                                     attr);
    }

    return AXIS2_FAILURE;
}

axis2_status_t AXIS2_CALL
axis2_endpoint_ref_add_metadata_attribute(
    axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env,
    axiom_attribute_t * attr)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    if (!(endpoint_ref->meta_attribute_list))
    {
        endpoint_ref->meta_attribute_list = axutil_array_list_create(env, 0);
        if (!(endpoint_ref->meta_attribute_list))
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }
    }

    if (endpoint_ref->meta_attribute_list && attr)
    {
        return axutil_array_list_add(endpoint_ref->meta_attribute_list, env,
                                     attr);
    }

    return AXIS2_FAILURE;
}

axis2_status_t AXIS2_CALL
axis2_endpoint_ref_add_extension(
    axis2_endpoint_ref_t * endpoint_ref,
    const axutil_env_t * env,
    axiom_node_t * extension_node)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    if (!(endpoint_ref->extension_list))
    {
        endpoint_ref->extension_list = axutil_array_list_create(env, 0);
        if (!(endpoint_ref->extension_list))
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }
    }

    if (endpoint_ref->extension_list && extension_node)
    {
        return axutil_array_list_add(endpoint_ref->extension_list, env,
                                     extension_node);
    }

    return AXIS2_FAILURE;
}
