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

struct axis2_stub
{
    axis2_svc_client_t *svc_client;
    axis2_options_t *options;
};

AXIS2_EXTERN axis2_stub_t *AXIS2_CALL
axis2_stub_create(
    const axutil_env_t * env)
{
    axis2_stub_t *stub = NULL;

    AXIS2_ENV_CHECK(env, NULL);

    stub = (axis2_stub_t *) AXIS2_MALLOC(env->allocator, sizeof(axis2_stub_t));

    if (!stub)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create stub.");
        return NULL;
    }
    stub->svc_client = NULL;
    stub->options = NULL;

    return stub;
}

AXIS2_EXTERN axis2_stub_t *AXIS2_CALL
axis2_stub_create_with_endpoint_ref_and_client_home(
    const axutil_env_t * env,
    axis2_endpoint_ref_t * endpoint_ref,
    const axis2_char_t * client_home)
{
    axis2_stub_t *stub = NULL;

    AXIS2_ENV_CHECK(env, NULL);
    AXIS2_PARAM_CHECK(env->error, endpoint_ref, NULL);

    stub = (axis2_stub_t *) axis2_stub_create(env);

    if (!stub)
    {
        return NULL;
    }
   
    stub->svc_client = axis2_svc_client_create(env, client_home);

    if (!stub->svc_client)
    {
        axis2_stub_free(stub, env);
        return NULL;
    }

    stub->options = axis2_options_create(env);
    if (!stub->options)
    {
        axis2_stub_free(stub, env);
        return NULL;
    }

    axis2_svc_client_set_options(stub->svc_client, env, stub->options);

    axis2_options_set_to(stub->options, env, endpoint_ref);

    return stub;
}

AXIS2_EXTERN axis2_stub_t *AXIS2_CALL
axis2_stub_create_with_endpoint_uri_and_client_home(
    const axutil_env_t * env,
    const axis2_char_t * endpoint_uri,
    const axis2_char_t * client_home)
{
    axis2_stub_t *stub = NULL;
    axis2_endpoint_ref_t *endpoint_ref = NULL;

    AXIS2_ENV_CHECK(env, NULL);
    AXIS2_PARAM_CHECK(env->error, endpoint_uri, NULL);

    endpoint_ref = axis2_endpoint_ref_create(env, endpoint_uri);
    if (!endpoint_ref)
    {
        return NULL;
    }
    stub = (axis2_stub_t *)
        axis2_stub_create_with_endpoint_ref_and_client_home(env, endpoint_ref,
                                                            client_home);

    if (!stub)
    {
        return NULL;
    }

    return stub;
}

void AXIS2_CALL
axis2_stub_free(
    axis2_stub_t * stub,
    const axutil_env_t * env)
{
    if (stub)
    {
        if (stub->svc_client)
        {
            axis2_svc_client_free(stub->svc_client, env);
        }
        
        AXIS2_FREE(env->allocator, stub);
    }
}

axis2_status_t AXIS2_CALL
axis2_stub_set_endpoint_ref(
    axis2_stub_t * stub,
    const axutil_env_t * env,
    axis2_endpoint_ref_t * endpoint_ref)
{
    AXIS2_PARAM_CHECK(env->error, endpoint_ref, AXIS2_FAILURE);
    axis2_options_set_to(stub->options, env, endpoint_ref);
    return AXIS2_SUCCESS;
}


axis2_status_t AXIS2_CALL
axis2_stub_set_endpoint_uri(
    axis2_stub_t * stub,
    const axutil_env_t * env,
    const axis2_char_t * endpoint_uri)
{
    axis2_endpoint_ref_t *endpoint_ref = NULL;

    AXIS2_PARAM_CHECK(env->error, endpoint_uri, AXIS2_FAILURE);

    endpoint_ref = axis2_endpoint_ref_create(env, endpoint_uri);
    if (!endpoint_ref)
    {
        return AXIS2_FAILURE;
    }
    axis2_options_set_to(stub->options, env, endpoint_ref);

    return AXIS2_SUCCESS;
}

axis2_status_t AXIS2_CALL
axis2_stub_set_use_separate_listener(
    axis2_stub_t * stub,
    const axutil_env_t * env,
    const axis2_bool_t use_separate_listener)
{
    return axis2_options_set_use_separate_listener(stub->options, env,
                                                   use_separate_listener);
}

axis2_status_t AXIS2_CALL
axis2_stub_engage_module(
    axis2_stub_t * stub,
    const axutil_env_t * env,
    const axis2_char_t * module_name)
{
    AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FAILURE);

    return axis2_svc_client_engage_module(stub->svc_client, env, module_name);
}

axis2_status_t AXIS2_CALL
axis2_stub_set_soap_version(
    axis2_stub_t * stub,
    const axutil_env_t * env,
    const int soap_version)
{
    if (!stub->options)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot set soap version. Stub option is not valid.");
        return AXIS2_FAILURE;
    }
    return axis2_options_set_soap_version(stub->options, env, soap_version);
}

const axis2_char_t *AXIS2_CALL
axis2_stub_get_svc_ctx_id(
    const axis2_stub_t * stub,
    const axutil_env_t * env)
{
    const axis2_svc_ctx_t *svc_ctx = NULL;
    const axis2_char_t *svc_ctx_id = NULL;

    AXIS2_PARAM_CHECK (env->error, stub, NULL);

    svc_ctx = axis2_svc_client_get_svc_ctx(stub->svc_client, env);
    svc_ctx_id = axis2_svc_ctx_get_svc_id(svc_ctx, env);
    return svc_ctx_id;
}

axis2_svc_client_t *AXIS2_CALL
axis2_stub_get_svc_client(
    const axis2_stub_t * stub,
    const axutil_env_t * env)
{
    AXIS2_PARAM_CHECK (env->error, stub, NULL);
    return stub->svc_client;
}

axis2_options_t *AXIS2_CALL
axis2_stub_get_options(
    const axis2_stub_t * stub,
    const axutil_env_t * env)
{
    return stub->options;
}
