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

#ifndef AXIS2_ENGINE_H
#define AXIS2_ENGINE_H

/**
 * @defgroup axis2_engine engine
 * @ingroup axis2_engine
 * engine has the send and receive functions that is the heart when providing
 * and consuming services. In Axis2 SOAP engine architecture, all the others
 * parts are build around the concept of the engine. There is only one engine
 * for both the server side and the client side, and the engine is not aware of
 * if it is invoked as an client or a service. engine supports both synchronous
 * and asynchronous messaging modes based on send and receive functions.
 * @{
 */

/**
  * @file axis2_engine.h
  */

#include <axis2_defines.h>
#include <axutil_array_list.h>
#include <axutil_env.h>
#include <axis2_conf_ctx.h>

#ifdef __cplusplus
extern "C"
{
#endif

    /** Type name for struct axis2_engine */
    typedef struct axis2_engine axis2_engine_t;

    struct axiom_soap_fault;

    /**
     * This methods represents the out flow of the Axis engine both at the 
     * server side as well as the client side. In this function, the 
     * execution chain is created using the phases of the out flow. 
     * All handlers at each out flow phase, which are ordered in the
     * deployment time are invoked in sequence here.
     * @param engine pointer to engine
     * @param env pointer to environment struct
     * @param msg_ctx pointer to message context representing current state
     * that is used when sending message
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE 
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_engine_send(
        axis2_engine_t * engine,
        const axutil_env_t * env,
        axis2_msg_ctx_t * msg_ctx);

    /**
     * This methods represents the in flow of the Axis engine,  both at the 
     * server side as well as the client side. In this function, the 
     * execution chain is created using the phases of the in flow. 
     * All handlers at each in flow phase, which are ordered in the
     * deployment time are invoked in sequence here.
     * @param engine pointer to engine
     * @param env pointer to environment struct
     * @param msg_ctx pointer to message context representing current state
     * that is used in receiving message
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE 
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_engine_receive(
        axis2_engine_t * engine,
        const axutil_env_t * env,
        axis2_msg_ctx_t * msg_ctx);

    /**
     * Sends a SOAP fault.
     * @param engine pointer to engine
     * @param env pointer to environment struct
     * @param msg_ctx pointer to message context that contains details of 
     * fault state
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE 
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_engine_send_fault(
        axis2_engine_t * engine,
        const axutil_env_t * env,
        axis2_msg_ctx_t * msg_ctx);

    /**
     * This is invoked when a SOAP fault is received.
     * @param engine pointer to engine
     * @param env pointer to environment struct
     * @param msg_ctx pointer to message context representing that contains
     * the details of receive state
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE 
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_engine_receive_fault(
        axis2_engine_t * engine,
        const axutil_env_t * env,
        axis2_msg_ctx_t * msg_ctx);

    /**
     * Creates a message context that represents the fault state based on 
     * current processing state.
     * @param engine pointer to engine
     * @param env pointer to environment struct
     * @param processing_context pointer to message context representing 
     * current processing context
     * @param code_value pointer to a string containing fault code
     * @param reason_text pointer to a string containing reason of the fault
     * @return pointer to message context representing the fault state
     */
    AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL

    axis2_engine_create_fault_msg_ctx(
        axis2_engine_t * engine,
        const axutil_env_t * env,
        axis2_msg_ctx_t * processing_context,
        const axis2_char_t * code_value,
        const axis2_char_t * reason_text);

    /**
     * Invokes the phases in the given array list of phases. The list of 
     * phases could be representing one of the flows. The two possible 
     * flows are in flow and out flow. Both of those flows can also have 
     * fault related representations, in fault flow and out fault flow.
     * Invoking a phase triggers the invocation of handlers the phase 
     * contain. 
     * @param engine pointer to engine
     * @param env pointer to environment struct
     * @param phases pointer to phases
     * @param msg_ctx pointer to message context containing current state
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE 
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_engine_invoke_phases(
        axis2_engine_t * engine,
        const axutil_env_t * env,
        axutil_array_list_t * phases,
        axis2_msg_ctx_t * msg_ctx);

    /**
     * Resumes phase invocation. While invoking the phases, one of the 
     * handlers in any phase could determine to pause the invocation. 
     * Often pausing happens to wait till some state is reached or some
     * task is complete. Once paused, the invocation has to be resumed 
     * using this function, which will resume the invocation from the paused 
     * handler in the paused phase and will continue till it is paused 
     * again or it completes invoking all the remaining handlers in the
     * remaining phases.
     * @param engine pointer to engine
     * @param env pointer to environment struct
     * @param phases pointer to phases
     * @param msg_ctx pointer to message context containing current paused 
     * state
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE 
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL

    axis2_engine_resume_invocation_phases(
        axis2_engine_t * engine,
        const axutil_env_t * env,
        axutil_array_list_t * phases,
        axis2_msg_ctx_t * msg_ctx);

    /**
     * Gets sender's SOAP fault code.
     * @param engine pointer to engine
     * @param env pointer to environment struct
     * @param soap_namespace pointer to SOAP namespace
     * @return pointer to SOAP fault code string
     */
    AXIS2_EXTERN const axis2_char_t *AXIS2_CALL

    axis2_engine_get_sender_fault_code(
        const axis2_engine_t * engine,
        const axutil_env_t * env,
        const axis2_char_t * soap_namespace);

    /**
     * Gets receiver's SOAP fault code.
     * @param engine pointer to engine
     * @param env pointer to environment struct
     * @param soap_namespace pointer to soap namespace
     */
    AXIS2_EXTERN const axis2_char_t *AXIS2_CALL

    axis2_engine_get_receiver_fault_code(
        const axis2_engine_t * engine,
        const axutil_env_t * env,
        const axis2_char_t * soap_namespace);

    /**
     * Frees engine struct.
     * @param engine pointer to engine
     * @param env pointer to environment struct
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE 
     */
    AXIS2_EXTERN void AXIS2_CALL
    axis2_engine_free(
        axis2_engine_t * engine,
        const axutil_env_t * env);

    /**
     * Resumes receive operation. It could be the case that receive was 
     * paused by one of the in flow handlers. In such a situation, this 
     * method could be used to resume the receive operation.
     * @param engine pointer to engine
     * @param env pointer to environment struct
     * @param msg_ctx pointer to message context
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE 
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_engine_resume_receive(
        axis2_engine_t * engine,
        const axutil_env_t * env,
        axis2_msg_ctx_t * msg_ctx);

    /**
     * Resumes send operation. It could be the case that send was 
     * paused by one of the out flow handlers. In such a situation, this 
     * method could be used to resume the send operation.
     * @param engine pointer to engine
     * @param env pointer to environment struct
     * @param msg_ctx pointer to message context
     * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE 
     */
    AXIS2_EXTERN axis2_status_t AXIS2_CALL
    axis2_engine_resume_send(
        axis2_engine_t * engine,
        const axutil_env_t * env,
        axis2_msg_ctx_t * msg_ctx);

    /**
     * Creates en engine struct instance.
     * @param env pointer to environment struct
     * @param conf_ctx pointer to configuration context struct
     * @return pointer to newly created engine struct
     */
    AXIS2_EXTERN axis2_engine_t *AXIS2_CALL
    axis2_engine_create(
        const axutil_env_t * env,
        axis2_conf_ctx_t * conf_ctx);

#ifdef __cplusplus
}
#endif

#endif                          /* AXIS2_ENGINE_H */
