/*
 * 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_msg_recv.h>
#include <axutil_param.h>
#include <axis2_description.h>
#include <axutil_class_loader.h>
#include <axis2_engine.h>
#include <axis2_core_utils.h>
#include <axutil_property.h>
#include <axiom_soap_envelope.h>
#include <axiom_soap_body.h>
#include <axutil_thread.h>

struct axis2_msg_recv
{
    axis2_char_t *scope;
	/**
	 * conf ctx is added to pass for the load_and_init_svc method
	 */
	axis2_conf_ctx_t *conf_ctx;

    void *derived;

    /**
     * This contain in out synchronous business invoke logic
     * @param msg_recv pointer to message receiver
     * @param env pointer to environment struct
     * @param in_msg_ctx pointer to in message context
     * @param out_msg_ctx pointer to out message context
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
     */
    axis2_status_t
    (
        AXIS2_CALL * invoke_business_logic)
    (
        axis2_msg_recv_t * msg_recv,
        const axutil_env_t * env,
        struct axis2_msg_ctx * in_msg_ctx,
        struct axis2_msg_ctx * out_msg_ctx);

    /**
     * This method is called from axis2_engine_receive method. This method's
     * actual implementation is decided from the create method of the 
     * extended message receiver object. There depending on the synchronous or
     * asynchronous type, receive method is assigned with the synchronous or
     * asynchronous implementation of receive.
     * @see raw_xml_in_out_msg_recv_create method where receive is assigned
     * to receive_sync
     * @param msg_recv pointer to message receiver
     * @param env pointer to environment struct
     * @param in_msg_ctx pointer to in message context
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
     */
    axis2_status_t
    (
        AXIS2_CALL * receive)
    (
        axis2_msg_recv_t * msg_recv,
        const axutil_env_t * env,
        struct axis2_msg_ctx * in_msg_ctx,
        void *callback_recv_param);

    axis2_status_t
    (
        AXIS2_CALL *load_and_init_svc)
( axis2_msg_recv_t *msg_recv,
const axutil_env_t *env,
struct axis2_svc *svc);

};

static axis2_status_t AXIS2_CALL
axis2_msg_recv_receive_impl(
    axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    void *callback_recv_param);

static axis2_status_t AXIS2_CALL
axis2_msg_recv_load_and_init_svc_impl(
    axis2_msg_recv_t *msg_recv,
    const axutil_env_t *env,
    struct axis2_svc *svc)
{
    axutil_param_t *impl_info_param = NULL;
    void *impl_class = NULL;

    AXIS2_ENV_CHECK(env, NULL);

    if(!svc)
    {
        return AXIS2_FAILURE;
    }

    impl_class = axis2_svc_get_impl_class(svc, env);
    if(impl_class)
    {
        return AXIS2_SUCCESS;
    }
    /* When we load the DLL we have to make sure that only one thread will load it */
    axutil_thread_mutex_lock(axis2_svc_get_mutex(svc, env));
    /* If more than one thread tries to acquires the lock, first thread loads the DLL.
     Others should not load the DLL */
    impl_class = axis2_svc_get_impl_class(svc, env);
    if(impl_class)
    {
        axutil_thread_mutex_unlock(axis2_svc_get_mutex(svc, env));
        return AXIS2_SUCCESS;
    }
    impl_info_param = axis2_svc_get_param(svc, env, AXIS2_SERVICE_CLASS);
    if(!impl_info_param)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_SVC, AXIS2_FAILURE);
        axutil_thread_mutex_unlock(axis2_svc_get_mutex(svc, env));
        return AXIS2_FAILURE;
    }

    axutil_allocator_switch_to_global_pool(env->allocator);

    axutil_class_loader_init(env);

    impl_class = axutil_class_loader_create_dll(env, impl_info_param);
    AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "loading the services from msg_recv_load_and_init_svc");

    if(impl_class)
    {
        axis2_svc_skeleton_t *skel = (axis2_svc_skeleton_t *)impl_class;
        axis2_conf_t *conf = NULL;
        conf = axis2_conf_ctx_get_conf(msg_recv->conf_ctx, env);
        if (skel->ops->init)
        {
            AXIS2_SVC_SKELETON_INIT(skel, env);
        }
        if (skel->ops->init_with_conf)
        {
            AXIS2_SVC_SKELETON_INIT_WITH_CONF(skel, env, conf);
        }
    }

    axis2_svc_set_impl_class(svc, env, impl_class);

    axutil_allocator_switch_to_local_pool(env->allocator);
    axutil_thread_mutex_unlock(axis2_svc_get_mutex(svc, env));
    return AXIS2_SUCCESS;
}

AXIS2_EXPORT axis2_msg_recv_t *AXIS2_CALL
axis2_msg_recv_create(
    const axutil_env_t * env)
{
    axis2_msg_recv_t *msg_recv = NULL;

    AXIS2_ENV_CHECK(env, NULL);

    msg_recv = (axis2_msg_recv_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_msg_recv_t));

    if(!msg_recv)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    msg_recv->conf_ctx = NULL;
    msg_recv->scope = axutil_strdup(env, "app*");
    msg_recv->derived = NULL;
    msg_recv->load_and_init_svc = axis2_msg_recv_load_and_init_svc_impl;
    msg_recv->receive = axis2_msg_recv_receive_impl;
    return msg_recv;
}

AXIS2_EXPORT void AXIS2_CALL
axis2_msg_recv_free(
    axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, void);

    if(msg_recv->scope)
    {
        AXIS2_FREE(env->allocator, msg_recv->scope);
    }

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

    return;
}

AXIS2_EXPORT axis2_svc_skeleton_t *AXIS2_CALL
axis2_msg_recv_make_new_svc_obj(
    axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env,
    struct axis2_msg_ctx * msg_ctx)
{
    struct axis2_svc *svc = NULL;
    struct axis2_op_ctx *op_ctx = NULL;
    struct axis2_svc_ctx *svc_ctx = NULL;
    axutil_param_t *impl_info_param = NULL;
    void *impl_class = NULL;

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

    op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
    svc_ctx = axis2_op_ctx_get_parent(op_ctx, env);
    svc = axis2_svc_ctx_get_svc(svc_ctx, env);
    if(!svc)
    {
        return NULL;
    }

    impl_class = axis2_svc_get_impl_class(svc, env);
    if(impl_class)
    {
        return impl_class;
    }
    else
    {
        /* When we load the DLL we have to make sure that only one thread will load it */
        axutil_thread_mutex_lock(axis2_svc_get_mutex(svc, env));
        /* If more than one thread tries to acquires the lock, first thread loads the DLL.
         Others should not load the DLL */
        impl_class = axis2_svc_get_impl_class(svc, env);
        if(impl_class)
        {
            axutil_thread_mutex_unlock(axis2_svc_get_mutex(svc, env));
            return impl_class;
        }
        impl_info_param = axis2_svc_get_param(svc, env, AXIS2_SERVICE_CLASS);
        if(!impl_info_param)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_SVC, AXIS2_FAILURE);
            axutil_thread_mutex_unlock(axis2_svc_get_mutex(svc, env));
            return NULL;
        }

        axutil_allocator_switch_to_global_pool(env->allocator);

        axutil_class_loader_init(env);

        impl_class = axutil_class_loader_create_dll(env, impl_info_param);

        if(impl_class)
        {
            AXIS2_SVC_SKELETON_INIT((axis2_svc_skeleton_t *)impl_class, env);
        }

        axis2_svc_set_impl_class(svc, env, impl_class);

        axutil_allocator_switch_to_local_pool(env->allocator);
        axutil_thread_mutex_unlock(axis2_svc_get_mutex(svc, env));
        return impl_class;
    }
}

/*AXIS2_EXPORT axis2_svc_skeleton_t *AXIS2_CALL
axis2_msg_recv_get_impl_obj(
    axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env,
    struct axis2_msg_ctx * msg_ctx)
{
    struct axis2_svc *svc = NULL;
    struct axis2_op_ctx *op_ctx = NULL;
    struct axis2_svc_ctx *svc_ctx = NULL;

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

    op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
    svc_ctx = axis2_op_ctx_get_parent(op_ctx, env);
    svc = axis2_svc_ctx_get_svc(svc_ctx, env);
    if(!svc)
    {
        return NULL;
    }

    return axis2_msg_recv_make_new_svc_obj(msg_recv, env, msg_ctx);
}*/

AXIS2_EXPORT axis2_status_t AXIS2_CALL
axis2_msg_recv_set_scope(
    axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env,
    const axis2_char_t * scope)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, scope, AXIS2_FAILURE);

    if(msg_recv->scope)
    {
        AXIS2_FREE(env->allocator, msg_recv->scope);
    }
    msg_recv->scope = axutil_strdup(env, scope);
    if(!msg_recv->scope)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXPORT axis2_char_t *AXIS2_CALL
axis2_msg_recv_get_scope(
    axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env)
{
    return msg_recv->scope;
}

AXIS2_EXPORT axis2_status_t AXIS2_CALL
axis2_msg_recv_delete_svc_obj(
    axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx)
{
    axis2_svc_t *svc = NULL;
    axis2_op_ctx_t *op_ctx = NULL;
    axis2_svc_ctx_t *svc_ctx = NULL;
    axutil_param_t *impl_info_param = NULL;
    axutil_param_t *scope_param = NULL;
    axis2_char_t *param_value = NULL;
    axutil_dll_desc_t *dll_desc = NULL;

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

    op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env);
    svc_ctx = axis2_op_ctx_get_parent(op_ctx, env);
    svc = axis2_svc_ctx_get_svc(svc_ctx, env);
    if(!svc)
    {
        return AXIS2_FAILURE;
    }

    scope_param = axis2_svc_get_param(svc, env, AXIS2_SCOPE);
    if(scope_param)
    {
        param_value = axutil_param_get_value(scope_param, env);
    }
    if(param_value && (0 == axutil_strcmp(AXIS2_APPLICATION_SCOPE, param_value)))
    {
        return AXIS2_SUCCESS;
    }

    impl_info_param = axis2_svc_get_param(svc, env, AXIS2_SERVICE_CLASS);
    if(!impl_info_param)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_STATE_SVC, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    dll_desc = axutil_param_get_value(impl_info_param, env);
    return axutil_class_loader_delete_dll(env, dll_desc);
}

static axis2_status_t AXIS2_CALL
axis2_msg_recv_receive_impl(
    axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    void *callback_recv_param)
{
    axis2_msg_ctx_t *out_msg_ctx = NULL;
    axis2_engine_t *engine = NULL;
    axis2_conf_ctx_t *conf_ctx = NULL;
    axis2_op_ctx_t *op_ctx = NULL;
    axis2_svc_ctx_t *svc_ctx = NULL;
    axis2_status_t status = AXIS2_FAILURE;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
    AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "[axis2]Entry:axis2_msg_recv_receive_impl");
    out_msg_ctx = axis2_core_utils_create_out_msg_ctx(env, msg_ctx);
    if(!out_msg_ctx)
    {
        return AXIS2_FAILURE;
    }
    op_ctx = axis2_msg_ctx_get_op_ctx(out_msg_ctx, env);
    if(!op_ctx)
    {
        axis2_core_utils_reset_out_msg_ctx(env, out_msg_ctx);
        axis2_msg_ctx_free(out_msg_ctx, env);
        return AXIS2_FAILURE;
    }

    status = axis2_op_ctx_add_msg_ctx(op_ctx, env, out_msg_ctx);
    if(!status)
    {
        axis2_core_utils_reset_out_msg_ctx(env, out_msg_ctx);
        axis2_msg_ctx_free(out_msg_ctx, env);
        return status;
    }
    status = axis2_op_ctx_add_msg_ctx(op_ctx, env, msg_ctx);

    if(!status)
    {
        return status;
    }

    status = axis2_msg_recv_invoke_business_logic(msg_recv, env, msg_ctx, out_msg_ctx);
    if(AXIS2_SUCCESS != status)
    {
        axis2_core_utils_reset_out_msg_ctx(env, out_msg_ctx);
        axis2_msg_ctx_free(out_msg_ctx, env);
        return status;
    }
    svc_ctx = axis2_op_ctx_get_parent(op_ctx, env);
    conf_ctx = axis2_svc_ctx_get_conf_ctx(svc_ctx, env);
    engine = axis2_engine_create(env, conf_ctx);
    if(!engine)
    {
        axis2_msg_ctx_free(out_msg_ctx, env);
        return AXIS2_FAILURE;
    }
    if(axis2_msg_ctx_get_soap_envelope(out_msg_ctx, env))
    {
        axiom_soap_envelope_t *soap_envelope = axis2_msg_ctx_get_soap_envelope(out_msg_ctx, env);
        if(soap_envelope)
        {
            axiom_soap_body_t *body = axiom_soap_envelope_get_body(soap_envelope, env);
            if(body)
            {
                /* in case of a SOAP fault, we got to return failure so that
                 transport gets to know that it should send 500 */
                if(axiom_soap_body_has_fault(body, env))
                {
                    status = AXIS2_FAILURE;
                    axis2_msg_ctx_set_fault_soap_envelope(msg_ctx, env, soap_envelope);
                    axis2_msg_ctx_set_soap_envelope(out_msg_ctx, env, NULL);
                }
                else
                {
                    /* if it is two way and not a fault then send through engine.
                     if it is one way we do not need to do an engine send */
                    status = axis2_engine_send(engine, env, out_msg_ctx);
                }
            }
        }
    }
    axis2_engine_free(engine, env);

    /* Reset the out message context to avoid double freeing at http worker. For example if this is
     * not done here both in and out message context will try to free the transport out stream 
     * which will result in memory corruption.
     */
    if(!axis2_msg_ctx_is_paused(out_msg_ctx, env) && !axis2_msg_ctx_is_keep_alive(out_msg_ctx, env))
    {
        axis2_core_utils_reset_out_msg_ctx(env, out_msg_ctx);
    }
    AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "[axis2]Exit:axis2_msg_recv_receive_impl");
    return status;
}

AXIS2_EXPORT axis2_status_t AXIS2_CALL
axis2_msg_recv_set_invoke_business_logic(
    axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env,
    AXIS2_MSG_RECV_INVOKE_BUSINESS_LOGIC func)
{
    msg_recv->invoke_business_logic = func;
    return AXIS2_SUCCESS;
}

AXIS2_EXPORT axis2_status_t AXIS2_CALL
axis2_msg_recv_invoke_business_logic(
    axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env,
    struct axis2_msg_ctx * in_msg_ctx,
    struct axis2_msg_ctx * out_msg_ctx)
{
    return msg_recv->invoke_business_logic(msg_recv, env, in_msg_ctx, out_msg_ctx);
}

AXIS2_EXPORT axis2_status_t AXIS2_CALL
axis2_msg_recv_set_derived(
    axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env,
    void *derived)
{
    msg_recv->derived = derived;
    return AXIS2_SUCCESS;
}

AXIS2_EXPORT void *AXIS2_CALL
axis2_msg_recv_get_derived(
    const axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env)
{
    return msg_recv->derived;
}

AXIS2_EXPORT axis2_status_t AXIS2_CALL
axis2_msg_recv_set_receive(
    axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env,
    AXIS2_MSG_RECV_RECEIVE func)
{
    msg_recv->receive = func;
    return AXIS2_SUCCESS;
}

AXIS2_EXPORT axis2_status_t AXIS2_CALL
axis2_msg_recv_receive(
    axis2_msg_recv_t * msg_recv,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx,
    void *callback_recv_param)
{
    return msg_recv->receive(msg_recv, env, msg_ctx, callback_recv_param);
}

AXIS2_EXPORT axis2_status_t AXIS2_CALL
axis2_msg_recv_set_load_and_init_svc(
    axis2_msg_recv_t *msg_recv,
    const axutil_env_t *env,
    AXIS2_MSG_RECV_LOAD_AND_INIT_SVC func)
{
    msg_recv->load_and_init_svc = func;
    return AXIS2_SUCCESS;
}

AXIS2_EXPORT axis2_status_t AXIS2_CALL
axis2_msg_recv_load_and_init_svc(
    axis2_msg_recv_t *msg_recv,
    const axutil_env_t *env,
    struct axis2_svc *svc)
{
    if(msg_recv->load_and_init_svc)
    {
        return msg_recv->load_and_init_svc(msg_recv, env, svc);
    }
    else
    {
        /* message receivers without physical service (e.g : programatical service injection) */
        return AXIS2_SUCCESS;
    }
}
AXIS2_EXPORT void AXIS2_CALL
	axis2_msg_recv_set_conf_ctx(axis2_msg_recv_t *msg_recv,
	const axutil_env_t *env,
	struct axis2_conf_ctx *conf_ctx)
{
	msg_recv->conf_ctx = conf_ctx;
}

AXIS2_EXPORT struct axis2_conf_ctx* AXIS2_CALL
axis2_msg_recv_get_conf_ctx(
						   axis2_msg_recv_t *msg_recv,
						   const axutil_env_t *env)
{
	if(msg_recv)
		return msg_recv->conf_ctx;
	return NULL;
}
