/*
 * 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_wsdl_import.h>

/**
 * @brief Wsdl import struct impl
 *   Wsdl imports
 */
typedef struct axis2_wsdl_import_impl
{
    axis2_wsdl_import_t wsdl_import;
    axis2_char_t *location;
    axis2_char_t *namespace;

}
axis2_wsdl_import_impl_t;

#define AXIS2_INTF_TO_IMPL(wsdl_import) \
      ((axis2_wsdl_import_impl_t *)wsdl_import)

/************************* Function prototypes ********************************/

axis2_status_t AXIS2_CALL
axis2_wsdl_import_free(axis2_wsdl_import_t *wsdl_import,
        const axis2_env_t *env);

axis2_char_t *AXIS2_CALL
axis2_wsdl_import_get_namespace(axis2_wsdl_import_t *wsdl_import,
        const axis2_env_t *env);

axis2_status_t AXIS2_CALL
axis2_wsdl_import_set_namespace(axis2_wsdl_import_t *wsdl_import,
        const axis2_env_t *env,
        axis2_char_t *namespace);

axis2_char_t *AXIS2_CALL
axis2_wsdl_import_get_location(axis2_wsdl_import_t *wsdl_import,
        const axis2_env_t *env);

axis2_status_t AXIS2_CALL
axis2_wsdl_import_set_location(axis2_wsdl_import_t *wsdl_import,
        const axis2_env_t *env,
        axis2_char_t *location);

/************************** End of function prototypes ************************/

axis2_wsdl_import_t * AXIS2_CALL
axis2_wsdl_import_create(const axis2_env_t *env)
{
    axis2_wsdl_import_impl_t *wsdl_import_impl = NULL;

    AXIS2_ENV_CHECK(env, NULL);

    wsdl_import_impl = (axis2_wsdl_import_impl_t *) AXIS2_MALLOC(env->allocator,
            sizeof(axis2_wsdl_import_impl_t));
    if (NULL == wsdl_import_impl)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    wsdl_import_impl->namespace = NULL;
    wsdl_import_impl->location = NULL;
    wsdl_import_impl->wsdl_import.ops = NULL;
    wsdl_import_impl->wsdl_import.wsdl_component = NULL;

    wsdl_import_impl->wsdl_import.wsdl_component = axis2_wsdl_component_create(env);
    if (NULL == wsdl_import_impl->wsdl_import.wsdl_component)
    {
        axis2_wsdl_import_free(&(wsdl_import_impl->wsdl_import), env);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    wsdl_import_impl->wsdl_import.ops =
        AXIS2_MALLOC(env->allocator, sizeof(axis2_wsdl_import_ops_t));
    if (NULL == wsdl_import_impl->wsdl_import.ops)
    {
        axis2_wsdl_import_free(&(wsdl_import_impl->wsdl_import), env);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    wsdl_import_impl->wsdl_import.ops->free =  axis2_wsdl_import_free;
    wsdl_import_impl->wsdl_import.ops->get_namespace =
        axis2_wsdl_import_get_namespace;
    wsdl_import_impl->wsdl_import.ops->set_namespace =
        axis2_wsdl_import_set_namespace;
    wsdl_import_impl->wsdl_import.ops->get_location =
        axis2_wsdl_import_get_location;
    wsdl_import_impl->wsdl_import.ops->set_location =
        axis2_wsdl_import_set_location;

    return &(wsdl_import_impl->wsdl_import);
}

/***************************Function implementation****************************/

axis2_status_t AXIS2_CALL
axis2_wsdl_import_free(axis2_wsdl_import_t *wsdl_import,
        const axis2_env_t *env)
{
    axis2_wsdl_import_impl_t *import_impl = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    import_impl = AXIS2_INTF_TO_IMPL(wsdl_import);

    if (wsdl_import->ops)
        AXIS2_FREE(env->allocator, wsdl_import->ops);

    if (import_impl->namespace)
    {
        AXIS2_FREE(env->allocator, import_impl->namespace);
        import_impl->namespace = NULL;
    }

    if (import_impl->location)
    {
        AXIS2_FREE(env->allocator, import_impl->location);
        import_impl->location = NULL;
    }

    if (wsdl_import->wsdl_component)
    {
        AXIS2_WSDL_COMPONENT_FREE(wsdl_import->wsdl_component, env);
        wsdl_import->wsdl_component = NULL;
    }

    AXIS2_FREE(env->allocator, import_impl);
    import_impl = NULL;

    return AXIS2_SUCCESS;
}

axis2_char_t *AXIS2_CALL
axis2_wsdl_import_get_namespace(axis2_wsdl_import_t *wsdl_import,
        const axis2_env_t *env)
{
    AXIS2_ENV_CHECK(env, NULL);
    return AXIS2_INTF_TO_IMPL(wsdl_import)->namespace;
}

axis2_status_t AXIS2_CALL
axis2_wsdl_import_set_namespace(axis2_wsdl_import_t *wsdl_import,
        const axis2_env_t *env,
        axis2_char_t *namespace)
{
    axis2_wsdl_import_impl_t *import_impl = NULL;

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

    import_impl = AXIS2_INTF_TO_IMPL(wsdl_import);

    if (import_impl->namespace)
    {
        AXIS2_FREE(env->allocator, import_impl->namespace);
        import_impl->namespace = NULL;
    }
    import_impl->namespace = AXIS2_STRDUP(namespace, env);
    if (!import_impl->namespace)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

axis2_char_t *AXIS2_CALL
axis2_wsdl_import_get_location(axis2_wsdl_import_t *wsdl_import,
        const axis2_env_t *env)
{
    AXIS2_ENV_CHECK(env, NULL);
    return AXIS2_INTF_TO_IMPL(wsdl_import)->location;
}

axis2_status_t AXIS2_CALL
axis2_wsdl_import_set_location(axis2_wsdl_import_t *wsdl_import,
        const axis2_env_t *env,
        axis2_char_t *location)
{
    axis2_wsdl_import_impl_t *import_impl = NULL;

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

    import_impl = AXIS2_INTF_TO_IMPL(wsdl_import);

    if (import_impl->location)
    {
        AXIS2_FREE(env->allocator, import_impl->location);
        import_impl->location = NULL;
    }
    import_impl->location = AXIS2_STRDUP(location, env);
    if (!import_impl->location)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}
