/*
 * 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 <signal.h>
#include <axiom.h>
#include <axiom_soap.h>
#include <axis2_engine.h>
#include <axiom_mime_parser.h>
#include <axutil_http_chunked_stream.h>
#include <axis2_amqp_defines.h>
#include <axis2_amqp_util.h>
#include <axis2_amqp_request_processor.h>

void* AXIS2_THREAD_FUNC
axis2_amqp_request_processor_thread_function(
    axutil_thread_t* thread,
    void* request_data)
{
    axis2_status_t status = AXIS2_FAILURE;
    axutil_env_t* env = NULL;
    axutil_env_t* thread_env = NULL;
    axis2_amqp_request_processor_resource_pack_t* request_resource_pack = NULL;

#ifndef WIN32
#ifdef AXIS2_SVR_MULTI_THREADED
    signal(SIGPIPE, SIG_IGN);
#endif
#endif

    request_resource_pack = (axis2_amqp_request_processor_resource_pack_t*)request_data;

    env = request_resource_pack->env;
    thread_env = axutil_init_thread_env(env);

    /* Process Request */
    status = axis2_amqp_process_request(thread_env, request_resource_pack);

    if(status == AXIS2_SUCCESS)
    {
        AXIS2_LOG_INFO(thread_env->log, "Request Processed Successfully");
    }
    else
    {
        AXIS2_LOG_WARNING(thread_env->log, AXIS2_LOG_SI, "Error while Processing Request");
    }

    AXIS2_FREE(thread_env->allocator, request_resource_pack->request_content);
    AXIS2_FREE(thread_env->allocator, request_resource_pack->reply_to);
    AXIS2_FREE(thread_env->allocator, request_resource_pack->content_type);
    AXIS2_FREE(thread_env->allocator, request_resource_pack->soap_action);

    AXIS2_FREE(thread_env->allocator, request_resource_pack);

    if(thread_env)
    {
        thread_env = NULL;
    }

#ifdef AXIS2_SVR_MULTI_THREADED
    axutil_thread_pool_exit_thread(env->thread_pool, thread);
#endif

    return NULL;
}

axis2_status_t
axis2_amqp_process_request(
    const axutil_env_t* env,
    axis2_amqp_request_processor_resource_pack_t* request_resource_pack)
{
    axiom_xml_reader_t* xml_reader = NULL;
    axiom_stax_builder_t* stax_builder = NULL;
    axiom_soap_builder_t* soap_builder = NULL;
    axis2_transport_out_desc_t* out_desc = NULL;
    axis2_transport_in_desc_t* in_desc = NULL;
    axis2_msg_ctx_t* msg_ctx = NULL;
    axiom_soap_envelope_t* soap_envelope = NULL;
    axis2_engine_t* engine = NULL;
    const axis2_char_t* soap_ns_uri = NULL;
    axis2_bool_t is_soap_11 = AXIS2_FALSE;
    axis2_char_t *soap_body_str = NULL;
    int soap_body_len = 0;
    axis2_bool_t is_mtom = AXIS2_FALSE;
    axis2_status_t status = AXIS2_FAILURE;
    axutil_hash_t *binary_data_map = NULL;
    axiom_soap_body_t *soap_body = NULL;
    axutil_property_t* reply_to_property = NULL;

    /* Create msg_ctx */
    if(!request_resource_pack->conf_ctx)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Conf Context not Available");
        return AXIS2_FAILURE;
    }

    out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf(
        request_resource_pack->conf_ctx, env), env, AXIS2_TRANSPORT_ENUM_AMQP);
    if(!out_desc)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport Out Descriptor not Found");
        return AXIS2_FAILURE;
    }

    in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(request_resource_pack->conf_ctx,
        env), env, AXIS2_TRANSPORT_ENUM_AMQP);
    if(!in_desc)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport In Descriptor not Found");
        return AXIS2_FAILURE;
    }

    /* Create msg_ctx */
    msg_ctx = axis2_msg_ctx_create(env, request_resource_pack->conf_ctx, in_desc, out_desc);

    axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE);

    /* Handle MTOM */
    if(strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_MULTIPART_RELATED))
    {
        axis2_char_t* mime_boundary = axis2_amqp_util_get_value_from_content_type(env,
            request_resource_pack->content_type, AXIS2_AMQP_HEADER_CONTENT_TYPE_MIME_BOUNDARY);

        if(mime_boundary)
        {
            axiom_mime_parser_t *mime_parser = NULL;
            int soap_body_len = 0;
            axutil_param_t *buffer_size_param = NULL;
            axutil_param_t *max_buffers_param = NULL;
            axutil_param_t *attachment_dir_param = NULL;
            axis2_char_t *value_size = NULL;
            axis2_char_t *value_num = NULL;
            axis2_char_t *value_dir = NULL;
            int size = 0;
            int num = 0;

            mime_parser = axiom_mime_parser_create(env);

            buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE);
            if(buffer_size_param)
            {
                value_size = (axis2_char_t*)axutil_param_get_value(buffer_size_param, env);
                if(value_size)
                {
                    size = atoi(value_size);
                    axiom_mime_parser_set_buffer_size(mime_parser, env, size);
                }
            }

            max_buffers_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_MAX_BUFFERS);
            if(max_buffers_param)
            {
                value_num = (axis2_char_t*)axutil_param_get_value(max_buffers_param, env);
                if(value_num)
                {
                    num = atoi(value_num);
                    axiom_mime_parser_set_max_buffers(mime_parser, env, num);
                }
            }

            /* If this paramter is there mime_parser will cached the attachment 
             * using to the directory for large attachments. */
            attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR);
            if(attachment_dir_param)
            {
                value_dir = (axis2_char_t*)axutil_param_get_value(attachment_dir_param, env);
                if(value_dir)
                {
                    axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir);
                }
            }

            if(mime_parser)
            {
                axis2_callback_info_t *callback_ctx = NULL;
                axutil_stream_t *stream = NULL;

                callback_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t));

                stream = axutil_stream_create_basic(env);
                if(stream)
                {
                    axutil_stream_write(stream, env, request_resource_pack->request_content,
                        request_resource_pack->content_length);
                    callback_ctx->env = env;
                    callback_ctx->in_stream = stream;
                    callback_ctx->content_length = request_resource_pack->content_length;
                    callback_ctx->unread_len = request_resource_pack->content_length;
                    callback_ctx->chunked_stream = NULL;
                }

                /*binary_data_map = 
                 axiom_mime_parser_parse(mime_parser, env,
                 axis2_amqp_util_on_data_request,
                 (void*)callback_ctx,
                 mime_boundary);*/
                if(!binary_data_map)
                {
                    return AXIS2_FAILURE;
                }

                soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env);
                soap_body_len = axiom_mime_parser_get_soap_body_len(mime_parser, env);

                axutil_stream_free(stream, env);
                AXIS2_FREE(env->allocator, callback_ctx);
                axiom_mime_parser_free(mime_parser, env);
            }

            AXIS2_FREE(env->allocator, mime_boundary);
        }

        is_mtom = AXIS2_TRUE;
    }
    else
    {
        soap_body_str = request_resource_pack->request_content;
        soap_body_len = request_resource_pack->content_length;
    }

    soap_body_len = axutil_strlen(soap_body_str);

    xml_reader = axiom_xml_reader_create_for_memory(env, soap_body_str, soap_body_len, NULL,
        AXIS2_XML_PARSER_TYPE_BUFFER);
    if(!xml_reader)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create XML Reader");
        return AXIS2_FAILURE;
    }

    stax_builder = axiom_stax_builder_create(env, xml_reader);
    if(!stax_builder)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create StAX Builder");
        return AXIS2_FAILURE;
    }

    soap_ns_uri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI;

    if(request_resource_pack->content_type)
    {
        if(strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_TEXT_XML))
        {
            is_soap_11 = AXIS2_TRUE;
            soap_ns_uri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI;
        }
        /*if (strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_APPL_SOAP))
         {
         is_soap_11 = AXIS2_FALSE;
         soap_ns_uri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI;
         }
         else if (strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_TEXT_XML))
         {
         is_soap_11 = AXIS2_TRUE;
         soap_ns_uri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI;
         }*/
    }

    soap_builder = axiom_soap_builder_create(env, stax_builder, soap_ns_uri);
    if(!soap_builder)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create SOAP Builder");
        return AXIS2_FAILURE;
    }

    if(binary_data_map)
    {
        axiom_soap_builder_set_mime_body_parts(soap_builder, env, binary_data_map);
    }

    soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env);
    axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);

    soap_body = axiom_soap_envelope_get_body(soap_envelope, env);

    if(!soap_body)
    {
        return AXIS2_FAILURE;
    }

    /* SOAPAction */
    if(request_resource_pack->soap_action)
    {
        axis2_msg_ctx_set_soap_action(msg_ctx, env, axutil_string_create(env,
            request_resource_pack->soap_action));
    }

    /* SOAP version */
    axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap_11);

    /* Set ReplyTo in the msg_ctx as a property. This is used by the server when
     * 1. WS-A is not in use
     * 2. ReplyTo is an anonymous EPR - Sandesha2/Dual-channel */
    reply_to_property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, 0, 0,
        (void*)request_resource_pack->reply_to);
    axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_AMQP_MSG_CTX_PROPERTY_REPLY_TO,
        reply_to_property);

    engine = axis2_engine_create(env, request_resource_pack->conf_ctx);

    if(AXIS2_TRUE == axiom_soap_body_has_fault(soap_body, env))
    {
        status = axis2_engine_receive_fault(engine, env, msg_ctx);
    }
    else
    {
        status = axis2_engine_receive(engine, env, msg_ctx);
    }

    if(engine)
    {
        axis2_engine_free(engine, env);
    }

    if(soap_body_str && is_mtom)
    {
        AXIS2_FREE(env->allocator, soap_body_str);
    }

    return status;
}
