/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed 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_OP_CTX_H
#define AXIS2_OP_CTX_H


/**
  * @file axis2_op_ctx.h
  * @brief axis2 Message Context interface
  */

#include <axis2_defines.h>
#include <axis2_hash.h>
#include <axis2_env.h>
#include <axis2_msg_ctx.h>
#include <axis2_op.h>

#ifdef __cplusplus
extern "C"
{
#endif

/** 
 * @defgroup axis2_op_ctx Operation Context 
 * An op context represents a running "instance" of an op, which is
 * represented by an axis2_op struct. This concept is needed to allow
 * messages to be grouped into ops as in WSDL 2.0-speak ops are
 * essentially arbitrary message exchange patterns. So as messages are being
 * exchanged the op context remembers the state of where in the message
 * exchange pattern it is in.
 * <p/>
 * The base implementation of op context
 * supports MEPs which have one input message and/or one output message. That
 * is, it supports the all the MEPs that are in the WSDL 2.0 specification. In
 * order to support another MEP one must extend this struct.
 * @ingroup axis2_core_context
 * @{
 */
    
typedef struct axis2_op_ctx_ops axis2_op_ctx_ops_t;
typedef struct axis2_op_ctx axis2_op_ctx_t; 
struct axis2_svc_ctx;
    
/** 
 * @brief Message Context ops struct
 * Encapsulator struct for ops of axis2_op_ctx
 */  
struct axis2_op_ctx_ops
{
    axis2_ctx_t* (AXIS2_CALL *get_base)(struct axis2_op_ctx *op_ctx, 
                                                axis2_env_t **env);
    
    axis2_status_t (AXIS2_CALL *free)(struct axis2_op_ctx *op_ctx, 
                                       axis2_env_t **env);
    
    /**
     * The method is used to do the intialization of the axis2_op_ctx
     */
    axis2_status_t (AXIS2_CALL *init)(struct axis2_op_ctx *op_ctx, axis2_env_t **env, struct axis2_conf *conf);
    
    /**
     * @return Returns the op.
     */
    struct axis2_op* (AXIS2_CALL *get_op)(struct axis2_op_ctx *op_ctx, axis2_env_t **env);
    
    /**
     * Return the struct axis2_svc_ctx * in which this op_ctx lives.
     *
     * @return parent struct axis2_svc_ctx *
     */
    struct axis2_svc_ctx* (AXIS2_CALL *get_parent)(struct axis2_op_ctx *op_ctx, axis2_env_t **env);
    
    /**
     * When a new message is added to the <code>MEPContext</code> the logic
     * should be included remove the MEPContext from the table in the
     * <code>axis2_conf_ctx</code>. Example: IN_IN_OUT At the second IN
     * message the MEPContext should be removed from the AxisOperation
     *
     * @param msgContext
     */
    axis2_status_t (AXIS2_CALL *add_msg_ctx)(struct axis2_op_ctx *op_ctx, axis2_env_t **env, axis2_msg_ctx_t *msg_ctx);
    
    /**
     * @param message_id
     * @return
     * @throws AxisFault
     */
    axis2_msg_ctx_t* (AXIS2_CALL *get_msg_ctx)(struct axis2_op_ctx *op_ctx, 
        axis2_env_t **env, axis2_char_t *message_id);
    
    /**
     * Checks to see if the MEP is complete. i.e. whether all the messages that
     * are associated with the MEP has arrived and MEP is complete.
     *
     */
    axis2_bool_t (AXIS2_CALL *get_is_complete)(struct axis2_op_ctx *op_ctx, 
        axis2_env_t **env);
    
    axis2_status_t (AXIS2_CALL *set_complete)(struct axis2_op_ctx *op_ctx, 
        axis2_env_t **env, 
        axis2_bool_t is_complete);
    
    /**
     * Removes the pointers to this <code>op_ctx</code> in the
     * <code>axis2_conf_ctx</code>'s op_ctxaxis2_hash_t *so that this
     * <code>op_ctx</code> will eventually get garbage collected
     * along with the <code>axis2_msg_ctx_t *</code>'s it contains. Note that if
     * the caller wants to make sure its safe to clean up this op_ctx
     * he should call is_complete() first. However, in cases like IN_OPTIONAL_OUT
     * and OUT_OPTIONAL_IN, it is possibe this will get called without the MEP
     * being complete due to the optional nature of the MEP.
     */
    axis2_status_t (AXIS2_CALL *cleanup)(struct axis2_op_ctx *op_ctx, 
        axis2_env_t **env);
    
    axis2_status_t (AXIS2_CALL *set_parent)(struct axis2_op_ctx *op_ctx, 
        axis2_env_t **env, 
        struct axis2_svc_ctx *svc_ctx);
    
    axis2_hash_t* (AXIS2_CALL *get_msg_ctx_map)(struct axis2_op_ctx *op_ctx, 
        axis2_env_t **env);
    
};

/** 
 * @brief Message Context struct
  *	Axis2 Message Context
 */
struct axis2_op_ctx
{
    axis2_op_ctx_ops_t *ops;    
};

AXIS2_DECLARE(axis2_op_ctx_t*)
axis2_op_ctx_create(axis2_env_t **env, 
                    struct axis2_op *op,
                    struct axis2_svc_ctx * svc_ctx);
    
/************************** Start of function macros **************************/
#define AXIS2_OP_CTX_GET_BASE(op_ctx, env) ((op_ctx)->ops->get_base(op_ctx, env))
#define AXIS2_OP_CTX_FREE(op_ctx, env) ((op_ctx)->ops->free(op_ctx, env))
#define AXIS2_OP_CTX_INIT(op_ctx, env, conf) ((op_ctx)->ops->init(op_ctx, env, conf))
#define AXIS2_OP_CTX_GET_OP(op_ctx, env) ((op_ctx)->ops->get_op(op_ctx, env))
#define AXIS2_OP_CTX_GET_PARENT(op_ctx, env) ((op_ctx)->ops->get_parent(op_ctx, env))
#define AXIS2_OP_CTX_ADD_MSG_CTX(op_ctx, env, msg_ctx) ((op_ctx)->ops->add_msg_ctx(op_ctx, env, msg_ctx))
#define AXIS2_OP_CTX_GET_MSG_CTX(op_ctx, env, message_id) ((op_ctx)->ops->get_msg_ctx(op_ctx, env, message_id))
#define AXIS2_OP_CTX_GET_IS_COMPLETE(op_ctx, env) ((op_ctx)->ops->get_is_complete(op_ctx, env))
#define AXIS2_OP_CTX_SET_IS_COMPLETE(op_ctx, env, is_complete) ((op_ctx)->ops->set_complete(op_ctx, env, is_complete))
#define AXIS2_OP_CTX_CLEANUP(op_ctx, env) ((op_ctx)->ops->cleanup(op_ctx, env))
#define AXIS2_OP_CTX_SET_PARENT(op_ctx, env, svc_ctx) ((op_ctx)->ops->set_parent(op_ctx, env, svc_ctx))
#define AXIS2_OP_CTX_GET_MSG_CTX_MAP(op_ctx, env) ((op_ctx)->ops->get_msg_ctx_map(op_ctx, env))    

/************************** End of function macros ****************************/    

/** @} */
#ifdef __cplusplus
}
#endif

#endif                          /* AXIS2_OP_CTX_H */
