/*
 * 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_op_ctx.h>
#include <axis2_conf_ctx.h>
#include <axis2_op.h>
#include <axis2_const.h>
#include <axutil_hash.h>

struct axis2_op_ctx
{

    /** base context struct */
    axis2_ctx_t *base;

    /** parent of operation context is a service context instance */
    struct axis2_svc_ctx *parent;

    /** message context map */
    axis2_msg_ctx_t *msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_MAX];

    /**
     * the operation of which this is a running instance. The MEP of this
     * operation must be one of the 8 predefined ones in WSDL 2.0.
     */
    axis2_op_t *op;

    /** operation Message Exchange Pattern (MEP) */
    int op_mep;

    /** is complete? */
    axis2_bool_t is_complete;

    /** the global message_id -> op_ctx map which is stored in
     * the axis2_conf_ctx. We are caching it here for faster access.
     */
    axutil_hash_t *op_ctx_map;

    /** op qname */
    axutil_qname_t *op_qname;

    /** service qname */
    axutil_qname_t *svc_qname;
    /* mutex to synchronize the read/write operations */
    axutil_thread_mutex_t *mutex;
    axis2_bool_t response_written;
    axis2_bool_t is_in_use;

    int ref;
};

AXIS2_EXTERN axis2_op_ctx_t *AXIS2_CALL
axis2_op_ctx_create(
    const axutil_env_t * env,
    axis2_op_t * op,
    struct axis2_svc_ctx *svc_ctx)
{
    axis2_op_ctx_t *op_ctx = NULL;
    int i = 0;

    op_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_op_ctx_t));
    if(!op_ctx)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    op_ctx->base = NULL;
    op_ctx->parent = NULL;
    op_ctx->op = NULL;
    op_ctx->op_mep = 0;
    op_ctx->is_complete = AXIS2_FALSE;
    op_ctx->is_in_use = AXIS2_FALSE;
    op_ctx->op_ctx_map = NULL;
    op_ctx->op_qname = NULL;
    op_ctx->svc_qname = NULL;
    op_ctx->response_written = AXIS2_FALSE;
    op_ctx->mutex = axutil_thread_mutex_create(env->allocator, AXIS2_THREAD_MUTEX_DEFAULT);

    if(!op_ctx->mutex)
    {
        axis2_op_ctx_free(op_ctx, env);
        return NULL;
    }

    op_ctx->base = axis2_ctx_create(env);
    if(!(op_ctx->base))
    {
        axis2_op_ctx_free(op_ctx, env);
        return NULL;
    }

    if(op)
    {
        op_ctx->op = op;
    }

    for(i = 0; i < AXIS2_WSDL_MESSAGE_LABEL_MAX; i++)
    {
        op_ctx->msg_ctx_array[i] = NULL;
    }

    if(op_ctx->op)
    {
        op_ctx->op_qname = (axutil_qname_t *)axis2_op_get_qname(op_ctx->op, env);
        op_ctx->op_mep = axis2_op_get_axis_specific_mep_const(op_ctx->op, env);
    }

    axis2_op_ctx_set_parent(op_ctx, env, svc_ctx);
    op_ctx->ref = 1;

    return op_ctx;
}

AXIS2_EXTERN axis2_ctx_t *AXIS2_CALL
axis2_op_ctx_get_base(
    const axis2_op_ctx_t * op_ctx,
    const axutil_env_t * env)
{
    return op_ctx->base;
}

AXIS2_EXTERN void AXIS2_CALL
axis2_op_ctx_free(
    struct axis2_op_ctx *op_ctx,
    const axutil_env_t * env)
{
    int i = 0;
    if(--(op_ctx->ref) > 0)
    {
        return;
    }
    if(op_ctx->is_in_use)
    {
        return;
    }

    if(op_ctx->base)
    {
        axis2_ctx_free(op_ctx->base, env);
    }

    for(i = 0; i < AXIS2_WSDL_MESSAGE_LABEL_MAX; i++)
    {
        if(op_ctx->msg_ctx_array[i])
        {
            axis2_msg_ctx_free(op_ctx->msg_ctx_array[i], env);
            op_ctx->msg_ctx_array[i] = NULL;
        }
    }

    if(op_ctx->mutex)
    {
        axutil_thread_mutex_destroy(op_ctx->mutex);
    }

    AXIS2_FREE(env->allocator, op_ctx);

    return;
}

AXIS2_EXTERN void AXIS2_CALL
axis2_op_ctx_destroy_mutex(
    struct axis2_op_ctx *op_ctx,
    const axutil_env_t * env)
{

    if(op_ctx->mutex)
    {
        axutil_thread_mutex_destroy(op_ctx->mutex);
        op_ctx->mutex = NULL;
    }
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_init(
    struct axis2_op_ctx *op_ctx,
    const axutil_env_t * env,
    struct axis2_conf *conf)
{
    int i = 0;

    if(op_ctx->op_qname && op_ctx->svc_qname)
    {
        axis2_svc_t *svc = NULL;
        axis2_char_t *svc_name = NULL;

        svc_name = axutil_qname_get_localpart(op_ctx->svc_qname, env);

        if(svc_name)
        {
            svc = axis2_conf_get_svc(conf, env, svc_name);

            if(svc)
            {
                op_ctx->op = axis2_svc_get_op_with_qname(svc, env, op_ctx->op_qname);
            }
        }
    }

    for(i = 0; i < AXIS2_WSDL_MESSAGE_LABEL_MAX; i++)
    {
        if(op_ctx->msg_ctx_array[i])
        {
            axis2_msg_ctx_init(op_ctx->msg_ctx_array[i], env, conf);
        }
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_op_t *AXIS2_CALL
axis2_op_ctx_get_op(
    const axis2_op_ctx_t * op_ctx,
    const axutil_env_t * env)
{
    return op_ctx->op;
}

AXIS2_EXTERN struct axis2_svc_ctx *AXIS2_CALL
axis2_op_ctx_get_parent(
    const axis2_op_ctx_t * op_ctx,
    const axutil_env_t * env)
{
    return op_ctx->parent;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_add_msg_ctx(
    struct axis2_op_ctx * op_ctx,
    const axutil_env_t * env,
    axis2_msg_ctx_t * msg_ctx)
{
    axis2_msg_ctx_t *out_msg_ctx = NULL;
    axis2_msg_ctx_t *in_msg_ctx = NULL;

    axutil_thread_mutex_lock(op_ctx->mutex);

    out_msg_ctx = op_ctx->msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_OUT];
    in_msg_ctx = op_ctx->msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_IN];

    if(out_msg_ctx && in_msg_ctx)
    {
        axutil_thread_mutex_unlock(op_ctx->mutex);
        return AXIS2_FAILURE;
    }

    if(!out_msg_ctx)
    {
        op_ctx->msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_OUT] = msg_ctx;
    }
    else
    {
        op_ctx->msg_ctx_array[AXIS2_WSDL_MESSAGE_LABEL_IN] = msg_ctx;
    }

    axutil_thread_mutex_unlock(op_ctx->mutex);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL
axis2_op_ctx_get_msg_ctx(
    const axis2_op_ctx_t * op_ctx,
    const axutil_env_t * env,
    const axis2_wsdl_msg_labels_t message_id)
{
    axutil_thread_mutex_lock(op_ctx->mutex);
    if(op_ctx->msg_ctx_array)
    {
        axis2_msg_ctx_t *rv = NULL;
        rv = op_ctx->msg_ctx_array[message_id];
        axutil_thread_mutex_unlock(op_ctx->mutex);
        return rv;
    }
    axutil_thread_mutex_unlock(op_ctx->mutex);
    return NULL;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_op_ctx_get_is_complete(
    const axis2_op_ctx_t * op_ctx,
    const axutil_env_t * env)
{
    return op_ctx->is_complete;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_set_complete(
    struct axis2_op_ctx * op_ctx,
    const axutil_env_t * env,
    axis2_bool_t is_complete)
{
    op_ctx->is_complete = is_complete;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_op_ctx_is_in_use(
    const axis2_op_ctx_t * op_ctx,
    const axutil_env_t * env)
{
    return op_ctx->is_in_use;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_set_in_use(
    struct axis2_op_ctx * op_ctx,
    const axutil_env_t * env,
    axis2_bool_t is_in_use)
{
    op_ctx->is_in_use = is_in_use;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_cleanup(
    struct axis2_op_ctx * op_ctx,
    const axutil_env_t * env)
{
    int i = 0;

    for(i = 0; i < AXIS2_WSDL_MESSAGE_LABEL_MAX; i++)
    {
        if(op_ctx->msg_ctx_array[i])
        {
            axis2_msg_ctx_free(op_ctx->msg_ctx_array[i], env);
            op_ctx->msg_ctx_array[i] = NULL;
        }
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_set_parent(
    struct axis2_op_ctx * op_ctx,
    const axutil_env_t * env,
    struct axis2_svc_ctx * svc_ctx)
{
    if(svc_ctx)
    {
        op_ctx->parent = svc_ctx;
    }

    if(op_ctx->parent) /* that is if there is a service context associated */
    {
        axis2_conf_ctx_t *conf_ctx = NULL;
        conf_ctx = axis2_svc_ctx_get_conf_ctx(op_ctx->parent, env);
        if(conf_ctx)
        {
            op_ctx->op_ctx_map = axis2_conf_ctx_get_op_ctx_map(conf_ctx, env);
        }
        op_ctx->svc_qname = (axutil_qname_t *)axis2_svc_get_qname(axis2_svc_ctx_get_svc(
            op_ctx->parent, env), env);
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_msg_ctx_t **AXIS2_CALL
axis2_op_ctx_get_msg_ctx_map(
    const axis2_op_ctx_t * op_ctx,
    const axutil_env_t * env)
{
    return (axis2_msg_ctx_t **)(op_ctx->msg_ctx_array);
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axis2_op_ctx_get_response_written(
    const axis2_op_ctx_t * op_ctx,
    const axutil_env_t * env)
{
    if(op_ctx)
        return op_ctx->response_written;
    else
        return AXIS2_FALSE;

}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_set_response_written(
    axis2_op_ctx_t * op_ctx,
    const axutil_env_t * env,
    const axis2_bool_t written)
{
    if(op_ctx)
    {
        op_ctx->response_written = written;
    }
    else
    {
        return AXIS2_FAILURE;
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_op_ctx_increment_ref(
    axis2_op_ctx_t * op_ctx,
    const axutil_env_t * env)
{
    op_ctx->ref++;
    return AXIS2_SUCCESS;
}

