/*
 * 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_options.h>
#include <axis2_const.h>
#include <axutil_hash.h>
#include <axiom_soap_const.h>
#include <axis2_msg_info_headers.h>
#include <axutil_array_list.h>
#include <axis2_http_transport.h>

struct axis2_options
{

    /** parent options */
    axis2_options_t *parent;

    axutil_hash_t *properties;

    axis2_char_t *soap_version_uri;

    int soap_version;

    long timeout_in_milli_seconds;

    axis2_bool_t use_separate_listener;

    /** addressing specific properties */
    axis2_msg_info_headers_t *msg_info_headers;

    axis2_transport_receiver_t *receiver;

    axis2_transport_in_desc_t *transport_in;

    AXIS2_TRANSPORT_ENUMS transport_in_protocol;

    /** for sending and receiving messages */
    axis2_transport_out_desc_t *transport_out;
    AXIS2_TRANSPORT_ENUMS sender_transport_protocol;

    axis2_bool_t manage_session;
    axis2_bool_t enable_mtom;
    axutil_string_t *soap_action;
    axis2_bool_t xml_parser_reset;
};

AXIS2_EXTERN axis2_options_t *AXIS2_CALL
axis2_options_create(
    const axutil_env_t * env)
{
    axis2_options_t *options = NULL;

    AXIS2_ENV_CHECK(env, NULL);

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

    options->parent = NULL;
    options->properties = NULL;
    options->soap_version_uri = NULL;
    options->timeout_in_milli_seconds = -1;
    options->use_separate_listener = -1;
    options->receiver = NULL;
    options->transport_in = NULL;
    options->transport_in_protocol = AXIS2_TRANSPORT_ENUM_MAX;
    options->transport_out = NULL;
    options->sender_transport_protocol = AXIS2_TRANSPORT_ENUM_MAX;
    options->manage_session = -1;
    options->soap_version = AXIOM_SOAP12;
    options->enable_mtom = AXIS2_FALSE;
    options->soap_action = NULL;
    options->xml_parser_reset = AXIS2_TRUE;

    options->msg_info_headers = axis2_msg_info_headers_create(env, NULL, NULL);
    if(!options->msg_info_headers)
    {
        axis2_options_free(options, env);
        return NULL;
    }

    options->properties = axutil_hash_make(env);
    if(!options->properties)
    {
        axis2_options_free(options, env);
        return NULL;
    }

    return options;
}

AXIS2_EXTERN axis2_options_t *AXIS2_CALL
axis2_options_create_with_parent(
    const axutil_env_t * env,
    axis2_options_t * parent)
{

    axis2_options_t *options = NULL;

    options = axis2_options_create(env);

    if(options)
    {
        options->parent = parent;
    }
    return options;
}

AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
axis2_options_get_action(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    const axis2_char_t *action = NULL;
    action = axis2_msg_info_headers_get_action(options->msg_info_headers, env);

    if(!action && options->parent)
    {
        return axis2_options_get_action(options->parent, env);
    }

    return action;
}

AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL
axis2_options_get_fault_to(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    axis2_endpoint_ref_t *fault_to = NULL;

    fault_to = axis2_msg_info_headers_get_fault_to(options->msg_info_headers, env);

    if(!fault_to && options->parent)
    {
        return axis2_options_get_fault_to(options->parent, env);
    }

    return fault_to;
}

AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL
axis2_options_get_from(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    axis2_endpoint_ref_t *from = NULL;

    from = axis2_msg_info_headers_get_from(options->msg_info_headers, env);

    if(!from && options->parent)
    {
        return axis2_options_get_from(options->parent, env);
    }

    return from;
}

AXIS2_EXTERN axis2_transport_receiver_t *AXIS2_CALL
axis2_options_get_transport_receiver(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    if(!options->receiver && options->parent)
    {
        return axis2_options_get_transport_receiver(options->parent, env);
    }

    return options->receiver;
}

AXIS2_EXTERN axis2_transport_in_desc_t *AXIS2_CALL
axis2_options_get_transport_in(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    if(!options->transport_in && options->parent)
    {
        return axis2_options_get_transport_in(options->parent, env);
    }

    return options->transport_in;
}

AXIS2_EXTERN AXIS2_TRANSPORT_ENUMS AXIS2_CALL
axis2_options_get_transport_in_protocol(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    if(options->parent)
    {
        return axis2_options_get_transport_in_protocol(options->parent, env);
    }

    return options->transport_in_protocol;
}

AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
axis2_options_get_message_id(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    const axis2_char_t *message_id = NULL;

    message_id = axis2_msg_info_headers_get_message_id(options->msg_info_headers, env);

    if(!message_id && options->parent)
    {
        return axis2_options_get_message_id(options->parent, env);
    }

    return message_id;
}

AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axis2_options_get_properties(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    if(!axutil_hash_count(options->properties) && options->parent)
    {
        return axis2_options_get_properties(options->parent, env);
    }

    return options->properties;
}

AXIS2_EXTERN void *AXIS2_CALL
axis2_options_get_property(
    const axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_char_t * key)
{
    void *property = NULL;

    property = axutil_hash_get(options->properties, key, AXIS2_HASH_KEY_STRING);

    if(!property && options->parent)
    {
        return axis2_options_get_property(options->parent, env, key);
    }

    return property;
}

AXIS2_EXTERN axis2_relates_to_t *AXIS2_CALL
axis2_options_get_relates_to(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    axis2_relates_to_t *relates_to = NULL;

    relates_to = axis2_msg_info_headers_get_relates_to(options->msg_info_headers, env);

    if(!relates_to && options->parent)
    {
        return axis2_options_get_relates_to(options->parent, env);
    }

    return relates_to;
}

AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL
axis2_options_get_reply_to(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    axis2_endpoint_ref_t *reply_to = NULL;

    reply_to = axis2_msg_info_headers_get_reply_to(options->msg_info_headers, env);

    if(!reply_to && options->parent)
    {
        return axis2_options_get_reply_to(options->parent, env);
    }

    return reply_to;
}

AXIS2_EXTERN axis2_transport_out_desc_t *AXIS2_CALL
axis2_options_get_transport_out(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    if(!options->transport_out && options->parent)
    {
        return axis2_options_get_transport_out(options->parent, env);
    }

    return options->transport_out;
}

AXIS2_EXTERN AXIS2_TRANSPORT_ENUMS AXIS2_CALL
axis2_options_get_sender_transport_protocol(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    if(options->parent)
    {
        return axis2_options_get_sender_transport_protocol(options->parent, env);
    }

    return options->sender_transport_protocol;
}

AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
axis2_options_get_soap_version_uri(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    if(!options->soap_version_uri && options->parent)
    {
        return axis2_options_get_soap_version_uri(options->parent, env);
    }

    if(options->soap_version_uri)
    {
        return options->soap_version_uri;
    }
    return AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI;

}

AXIS2_EXTERN long AXIS2_CALL
axis2_options_get_timeout_in_milli_seconds(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    if(options->timeout_in_milli_seconds == -1)
    {
        if(options->parent)
        {
            return axis2_options_get_timeout_in_milli_seconds(options->parent, env);
        }
        else
        {
            return AXIS2_DEFAULT_TIMEOUT_MILLISECONDS;
        }
    }

    return options->timeout_in_milli_seconds;
}

AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL
axis2_options_get_to(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    axis2_endpoint_ref_t *to = NULL;

    to = axis2_msg_info_headers_get_to(options->msg_info_headers, env);

    if(!to && options->parent)
    {
        return axis2_options_get_to(options->parent, env);
    }

    return to;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_options_get_use_separate_listener(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    if(options->use_separate_listener == -1)
    {
        if(options->parent)
        {
            return axis2_options_get_use_separate_listener(options->parent, env);
        }
        else
        {
            return AXIS2_FALSE;
        }
    }

    return options->use_separate_listener;
}

AXIS2_EXTERN axis2_options_t *AXIS2_CALL
axis2_options_get_parent(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    return options->parent;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_parent(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_options_t * parent)
{
    options->parent = (axis2_options_t *)parent;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_action(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_char_t * action)
{
    axis2_msg_info_headers_set_action(options->msg_info_headers, env, action);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_fault_to(
    axis2_options_t * options,
    const axutil_env_t * env,
    axis2_endpoint_ref_t * fault_to)
{
    axis2_msg_info_headers_set_fault_to(options->msg_info_headers, env, fault_to);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_from(
    axis2_options_t * options,
    const axutil_env_t * env,
    axis2_endpoint_ref_t * from)
{
    axis2_msg_info_headers_set_from(options->msg_info_headers, env, from);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_to(
    axis2_options_t * options,
    const axutil_env_t * env,
    axis2_endpoint_ref_t * to)
{
    axis2_msg_info_headers_set_to(options->msg_info_headers, env, to);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_transport_receiver(
    axis2_options_t * options,
    const axutil_env_t * env,
    axis2_transport_receiver_t * receiver)
{
    options->receiver = receiver;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_transport_in(
    axis2_options_t * options,
    const axutil_env_t * env,
    axis2_transport_in_desc_t * transport_in)
{
    options->transport_in = transport_in;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_transport_in_protocol(
    axis2_options_t * options,
    const axutil_env_t * env,
    const AXIS2_TRANSPORT_ENUMS transport_in_protocol)
{
    options->transport_in_protocol = transport_in_protocol;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_message_id(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_char_t * message_id)
{
    axis2_msg_info_headers_set_message_id(options->msg_info_headers, env, message_id);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_properties(
    axis2_options_t * options,
    const axutil_env_t * env,
    axutil_hash_t * properties)
{
    if(options->properties)
    {
        axutil_hash_free(options->properties, env);
    }
    options->properties = properties;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_property(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_char_t * property_key,
    const void *property)
{
    axutil_hash_set(options->properties, property_key, AXIS2_HASH_KEY_STRING, property);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_relates_to(
    axis2_options_t * options,
    const axutil_env_t * env,
    axis2_relates_to_t * relates_to)
{
    axis2_msg_info_headers_set_relates_to(options->msg_info_headers, env, relates_to);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_reply_to(
    axis2_options_t * options,
    const axutil_env_t * env,
    axis2_endpoint_ref_t * reply_to)
{
    axis2_msg_info_headers_set_reply_to(options->msg_info_headers, env, reply_to);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_transport_out(
    axis2_options_t * options,
    const axutil_env_t * env,
    axis2_transport_out_desc_t * transport_out)
{
    options->transport_out = transport_out;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_sender_transport(
    axis2_options_t * options,
    const axutil_env_t * env,
    const AXIS2_TRANSPORT_ENUMS sender_transport,
    axis2_conf_t * conf)
{
    options->transport_out = axis2_conf_get_transport_out(conf, env, sender_transport);

    if(!options->transport_out)
    {
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_soap_version_uri(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_char_t * soap_version_uri)
{
    if(options->soap_version_uri)
    {
        AXIS2_FREE(env->allocator, options->soap_version_uri);
        options->soap_version_uri = NULL;
    }

    if(soap_version_uri)
    {
        options->soap_version_uri = axutil_strdup(env, soap_version_uri);
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_timeout_in_milli_seconds(
    axis2_options_t * options,
    const axutil_env_t * env,
    const long timeout_in_milli_seconds)
{
    options->timeout_in_milli_seconds = timeout_in_milli_seconds;
    /* set the property AXIS2_HTTP_CONNECTION_TIMEOUT,
     * to be picked up by http_sender
     */
    if(options->timeout_in_milli_seconds > 0)
    {
        axis2_char_t time_str[19]; /* supports 18 digit timeout */
        axutil_property_t *property = axutil_property_create(env);
        sprintf(time_str, "%ld", options->timeout_in_milli_seconds);
        if(property)
        {
            axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST);
            axutil_property_set_value(property, env, axutil_strdup(env, time_str));
            axis2_options_set_property(options, env, AXIS2_HTTP_CONNECTION_TIMEOUT, property);
        }
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_transport_info(
    axis2_options_t * options,
    const axutil_env_t * env,
    const AXIS2_TRANSPORT_ENUMS sender_transport,
    const AXIS2_TRANSPORT_ENUMS receiver_transport,
    const axis2_bool_t use_separate_listener)
{
    /*
     here we check for the legal combination
     */
    if(!use_separate_listener)
    {
        if(sender_transport != receiver_transport)
        {
            return AXIS2_FAILURE;
        }
    }
    else
    {
        axis2_options_set_use_separate_listener(options, env, use_separate_listener);
    }
    axis2_options_set_transport_in_protocol(options, env, receiver_transport);
    options->sender_transport_protocol = sender_transport;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_use_separate_listener(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_bool_t use_separate_listener)
{
    axutil_property_t *property = NULL;

    options->use_separate_listener = use_separate_listener;

    if(use_separate_listener)
    {
        property = axutil_property_create(env);
        axutil_property_set_value(property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
        axis2_options_set_property(options, env, AXIS2_USE_SEPARATE_LISTENER, property);
    }
    else
    {
        property = axutil_property_create(env);
        axutil_property_set_value(property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
        axis2_options_set_property(options, env, AXIS2_USE_SEPARATE_LISTENER, property);
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_add_reference_parameter(
    axis2_options_t * options,
    const axutil_env_t * env,
    axiom_node_t * reference_parameter)
{
    axis2_msg_info_headers_add_ref_param(options->msg_info_headers, env, reference_parameter);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_manage_session(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_bool_t manage_session)
{
    options->manage_session = manage_session;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_options_get_manage_session(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    if(options->manage_session == -1)
    {
        if(options->parent)
        {
            return axis2_options_get_manage_session(options->parent, env);
        }
        else
        {
            return AXIS2_FALSE;
        }
    }

    return options->manage_session;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_msg_info_headers(
    axis2_options_t * options,
    const axutil_env_t * env,
    axis2_msg_info_headers_t * msg_info_headers)
{
    if(options->msg_info_headers)
    {
        axis2_msg_info_headers_free(options->msg_info_headers, env);
    }

    options->msg_info_headers = msg_info_headers;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_msg_info_headers_t *AXIS2_CALL
axis2_options_get_msg_info_headers(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    return options->msg_info_headers;
}

AXIS2_EXTERN void AXIS2_CALL
axis2_options_free(
    axis2_options_t * options,
    const axutil_env_t * env)
{
    if(options->properties)
    {
        axutil_hash_index_t *hi = NULL;
        void *val = NULL;
        const void *key = NULL;
        for(hi = axutil_hash_first(options->properties, env); hi; hi = axutil_hash_next(env, hi))
        {
            axutil_property_t *property = NULL;

            axutil_hash_this(hi, &key, NULL, &val);
            property = (axutil_property_t *)val;

            if(property)
            {
                axutil_property_free(property, env);
            }
        }
        axutil_hash_free(options->properties, env);
    }

    if(options->soap_version_uri)
    {
        AXIS2_FREE(env->allocator, options->soap_version_uri);
    }

    if(options->msg_info_headers)
    {
        axis2_msg_info_headers_free(options->msg_info_headers, env);
    }

    if(options->soap_action)
    {
        axutil_string_free(options->soap_action, env);
    }

    AXIS2_FREE(env->allocator, options);
}

AXIS2_EXTERN int AXIS2_CALL
axis2_options_get_soap_version(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    return options->soap_version;

}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_soap_version(
    axis2_options_t * options,
    const axutil_env_t * env,
    const int soap_version)
{
    if(soap_version == AXIOM_SOAP11)
    {
        options->soap_version = soap_version;
        axis2_options_set_soap_version_uri(options, env, AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI);
    }
    else
    {
        options->soap_version = AXIOM_SOAP12;
        axis2_options_set_soap_version_uri(options, env, AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_enable_mtom(
    axis2_options_t * options,
    const axutil_env_t * env,
    axis2_bool_t enable_mtom)
{
    options->enable_mtom = enable_mtom;

    if(enable_mtom)
    {
        axutil_property_t *property = axutil_property_create(env);
        if(property)
        {
            axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST);
            axutil_property_set_value(property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
            axis2_options_set_property(options, env, AXIS2_ENABLE_MTOM, property);
        }
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_options_get_enable_mtom(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    return options->enable_mtom;
}

AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axis2_options_get_soap_action(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    return options->soap_action;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_soap_action(
    axis2_options_t * options,
    const axutil_env_t * env,
    axutil_string_t * soap_action)
{
    if(options->soap_action)
    {
        axutil_string_free(options->soap_action, env);
        options->soap_action = NULL;
    }

    if(soap_action)
    {
        options->soap_action = axutil_string_clone(soap_action, env);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_options_get_xml_parser_reset(
    const axis2_options_t * options,
    const axutil_env_t * env)
{
    return options->xml_parser_reset;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_xml_parser_reset(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_bool_t xml_parser_reset)
{
    options->xml_parser_reset = xml_parser_reset;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_enable_rest(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_bool_t enable_rest)
{
    axutil_property_t *rest_property = NULL;

    if(enable_rest)
    {
        rest_property = axutil_property_create(env);
        axutil_property_set_value(rest_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
        axis2_options_set_property(options, env, AXIS2_ENABLE_REST, rest_property);
    }
    else
    {
        rest_property = axutil_property_create(env);
        axutil_property_set_value(rest_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
        axis2_options_set_property(options, env, AXIS2_ENABLE_REST, rest_property);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_test_http_auth(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_bool_t test_http_auth)
{
    axutil_property_t *test_auth_property = NULL;

    if(test_http_auth)
    {
        test_auth_property = axutil_property_create(env);
        axutil_property_set_value(test_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
        axis2_options_set_property(options, env, AXIS2_TEST_HTTP_AUTH, test_auth_property);
    }
    else
    {
        test_auth_property = axutil_property_create(env);
        axutil_property_set_value(test_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
        axis2_options_set_property(options, env, AXIS2_TEST_HTTP_AUTH, test_auth_property);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_test_proxy_auth(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_bool_t test_proxy_auth)
{
    axutil_property_t *test_auth_property = NULL;

    if(test_proxy_auth)
    {
        test_auth_property = axutil_property_create(env);
        axutil_property_set_value(test_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
        axis2_options_set_property(options, env, AXIS2_TEST_PROXY_AUTH, test_auth_property);
    }
    else
    {
        test_auth_property = axutil_property_create(env);
        axutil_property_set_value(test_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
        axis2_options_set_property(options, env, AXIS2_TEST_PROXY_AUTH, test_auth_property);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_http_method(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_char_t * http_method)
{
    axutil_property_t *method_property = NULL;

    method_property = axutil_property_create(env);
    axutil_property_set_value(method_property, env, axutil_strdup(env, http_method));
    axis2_options_set_property(options, env, AXIS2_HTTP_METHOD, method_property);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_http_headers(
    axis2_options_t * options,
    const axutil_env_t * env,
    axutil_array_list_t * http_header_list)
{
    axutil_property_t *headers_property = NULL;

    headers_property = axutil_property_create(env);
    axutil_property_set_value(headers_property, env, http_header_list);
    axis2_options_set_property(options, env, AXIS2_TRANSPORT_HEADER_PROPERTY, headers_property);
    axutil_property_set_free_func(headers_property, env, axutil_array_list_free_void_arg);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_proxy_auth_info(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_char_t * username,
    const axis2_char_t * password,
    const axis2_char_t * auth_type)
{
    axis2_bool_t force_proxy_auth = AXIS2_FALSE;
    axutil_property_t *prop_pw = NULL;
    axutil_property_t *prop_un = NULL;

    prop_un = axutil_property_create(env);
    axutil_property_set_value(prop_un, env, axutil_strdup(env, username));
    axis2_options_set_property(options, env, AXIS2_PROXY_AUTH_UNAME, prop_un);

    prop_pw = axutil_property_create(env);
    axutil_property_set_value(prop_pw, env, axutil_strdup(env, password));
    axis2_options_set_property(options, env, AXIS2_PROXY_AUTH_PASSWD, prop_pw);

    if(auth_type)
    {
        if((axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_BASIC) == 0) || (axutil_strcasecmp(
            auth_type, AXIS2_PROXY_AUTH_TYPE_DIGEST) == 0))
        {
            force_proxy_auth = AXIS2_TRUE;
        }
    }
    if(force_proxy_auth)
    {
        axutil_property_t *proxy_auth_property = axutil_property_create(env);
        axutil_property_t *proxy_auth_type_property = axutil_property_create(env);

        axutil_property_set_value(proxy_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
        axis2_options_set_property(options, env, AXIS2_FORCE_PROXY_AUTH, proxy_auth_property);

        axutil_property_set_value(proxy_auth_type_property, env, axutil_strdup(env, auth_type));
        axis2_options_set_property(options, env, AXIS2_PROXY_AUTH_TYPE, proxy_auth_type_property);
    }
    else
    {
        axutil_property_t *proxy_auth_property = axutil_property_create(env);
        axutil_property_set_value(proxy_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
        axis2_options_set_property(options, env, AXIS2_FORCE_PROXY_AUTH, proxy_auth_property);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_http_auth_info(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_char_t * username,
    const axis2_char_t * password,
    const axis2_char_t * auth_type)
{
    axis2_bool_t force_http_auth = AXIS2_FALSE;
    axutil_property_t *prop_un = NULL;
    axutil_property_t *prop_pw = NULL;

    prop_un = axutil_property_create(env);
    axutil_property_set_value(prop_un, env, axutil_strdup(env, username));
    axis2_options_set_property(options, env, AXIS2_HTTP_AUTH_UNAME, prop_un);

    prop_pw = axutil_property_create(env);
    axutil_property_set_value(prop_pw, env, axutil_strdup(env, password));
    axis2_options_set_property(options, env, AXIS2_HTTP_AUTH_PASSWD, prop_pw);

    if(auth_type)
    {
        if((axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_BASIC) == 0) || (axutil_strcasecmp(
            auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) == 0))
        {
            force_http_auth = AXIS2_TRUE;
        }
    }
    if(force_http_auth)
    {
        axutil_property_t *http_auth_property = axutil_property_create(env);
        axutil_property_t *http_auth_type_property = axutil_property_create(env);

        axutil_property_set_value(http_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
        axis2_options_set_property(options, env, AXIS2_FORCE_HTTP_AUTH, http_auth_property);

        axutil_property_set_value(http_auth_type_property, env, axutil_strdup(env, auth_type));
        axis2_options_set_property(options, env, AXIS2_HTTP_AUTH_TYPE, http_auth_type_property);
    }
    else
    {
        axutil_property_t *http_auth_property = axutil_property_create(env);
        axutil_property_set_value(http_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
        axis2_options_set_property(options, env, AXIS2_FORCE_HTTP_AUTH, http_auth_property);
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_ntlm_proxy_auth_info(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_char_t * username,
    const axis2_char_t * password,
    const int flags,
    const axis2_char_t * domain,
    const axis2_char_t * workstation,
    const axis2_char_t * auth_type)
{
    axis2_bool_t force_proxy_auth = AXIS2_FALSE;
    axis2_char_t temp_str[4];
    axutil_property_t *prop_pw = NULL;
    axutil_property_t *prop_un = NULL;
    axutil_property_t *prop_fg = NULL;
    axutil_property_t *prop_do = NULL;
    axutil_property_t *prop_wo = NULL;

    prop_un = axutil_property_create(env);
    axutil_property_set_value(prop_un, env, axutil_strdup(env, username));
    axis2_options_set_property(options, env, AXIS2_PROXY_AUTH_UNAME, prop_un);

    prop_pw = axutil_property_create(env);
    axutil_property_set_value(prop_pw, env, axutil_strdup(env, password));
    axis2_options_set_property(options, env, AXIS2_PROXY_AUTH_PASSWD, prop_pw);
    
    sprintf(temp_str, "%d", flags);
    prop_fg = axutil_property_create(env);
    axutil_property_set_value(prop_fg, env, axutil_strdup(env, temp_str));
    axis2_options_set_property(options, env, AXIS2_NTLM_AUTH_FLAGS, prop_fg);

    if(domain)
    {
        prop_do = axutil_property_create(env);
        axutil_property_set_value(prop_do, env, axutil_strdup(env, domain));
        axis2_options_set_property(options, env, AXIS2_NTLM_AUTH_DOMAIN, prop_do);
    }
    
    if(workstation)
    {
        prop_wo = axutil_property_create(env);
        axutil_property_set_value(prop_wo, env, axutil_strdup(env, workstation));
        axis2_options_set_property(options, env, AXIS2_NTLM_AUTH_WORKSTATION, prop_wo);
    }

    if(auth_type)
    {
        if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_NTLM) == 0)
        {
            force_proxy_auth = AXIS2_TRUE;
        }
    }
    if(force_proxy_auth)
    {
        axutil_property_t *proxy_auth_property = axutil_property_create(env);
        axutil_property_t *proxy_auth_type_property = axutil_property_create(env);

        axutil_property_set_value(proxy_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
        axis2_options_set_property(options, env, AXIS2_FORCE_PROXY_AUTH, proxy_auth_property);

        axutil_property_set_value(proxy_auth_type_property, env, axutil_strdup(env, auth_type));
        axis2_options_set_property(options, env, AXIS2_PROXY_AUTH_TYPE, proxy_auth_type_property);
    }
    else
    {
        axutil_property_t *proxy_auth_property = axutil_property_create(env);
        axutil_property_set_value(proxy_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
        axis2_options_set_property(options, env, AXIS2_FORCE_PROXY_AUTH, proxy_auth_property);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_options_set_ntlm_http_auth_info(
    axis2_options_t * options,
    const axutil_env_t * env,
    const axis2_char_t * username,
    const axis2_char_t * password,
    const int flags,
    const axis2_char_t * domain,
    const axis2_char_t * workstation,
    const axis2_char_t * auth_type)
{
    axis2_bool_t force_http_auth = AXIS2_FALSE;
    axis2_char_t temp_str[4];
    axutil_property_t *prop_un = NULL;
    axutil_property_t *prop_pw = NULL;
    axutil_property_t *prop_fg = NULL;
    axutil_property_t *prop_do = NULL;
    axutil_property_t *prop_wo = NULL;

    prop_un = axutil_property_create(env);
    axutil_property_set_value(prop_un, env, axutil_strdup(env, username));
    axis2_options_set_property(options, env, AXIS2_HTTP_AUTH_UNAME, prop_un);

    prop_pw = axutil_property_create(env);
    axutil_property_set_value(prop_pw, env, axutil_strdup(env, password));
    axis2_options_set_property(options, env, AXIS2_HTTP_AUTH_PASSWD, prop_pw);

    sprintf(temp_str, "%d", flags);
    prop_fg = axutil_property_create(env);
    axutil_property_set_value(prop_fg, env, axutil_strdup(env, temp_str));
    axis2_options_set_property(options, env, AXIS2_NTLM_AUTH_FLAGS, prop_fg);

    if(domain)
    {
        prop_do = axutil_property_create(env);
        axutil_property_set_value(prop_do, env, axutil_strdup(env, domain));
        axis2_options_set_property(options, env, AXIS2_NTLM_AUTH_DOMAIN, prop_do);
    }
    
    if(workstation)
    {
        prop_wo = axutil_property_create(env);
        axutil_property_set_value(prop_wo, env, axutil_strdup(env, workstation));
        axis2_options_set_property(options, env, AXIS2_NTLM_AUTH_WORKSTATION, prop_wo);
    }


    if(auth_type)
    {
        if(axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_NTLM) == 0)
        {
            force_http_auth = AXIS2_TRUE;
        }
    }
    if(force_http_auth)
    {
        axutil_property_t *http_auth_property = axutil_property_create(env);
        axutil_property_t *http_auth_type_property = axutil_property_create(env);

        axutil_property_set_value(http_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
        axis2_options_set_property(options, env, AXIS2_FORCE_HTTP_AUTH, http_auth_property);

        axutil_property_set_value(http_auth_type_property, env, axutil_strdup(env, auth_type));
        axis2_options_set_property(options, env, AXIS2_HTTP_AUTH_TYPE, http_auth_type_property);
    }
    else
    {
        axutil_property_t *http_auth_property = axutil_property_create(env);
        axutil_property_set_value(http_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
        axis2_options_set_property(options, env, AXIS2_FORCE_HTTP_AUTH, http_auth_property);
    }

    return AXIS2_SUCCESS;
}

