/*
* 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_MODULE_H
#define AXIS2_MODULE_H

/** 
 * @defgroup axis2_module module
 * @ingroup axis2_desc
 * Every module provides an implementation of struct interface. Modules are in 
 * one of two states: "available" or "initialized". All modules that the run-time
 * detects (from the repository modules directory) are said to be in the 
 * "available" state. If some service indicates a dependency on this
 * module then the module is initialized (once for the life time of the system) 
 * and the state changes to "initialized".
 * Any module which is in the "initialized" state can be engaged as needed
 * by the engine to respond to a message. Module engagement is done by 
 * deployment engine using module.xml. 
 * @{
 */

/**
 * @file axis2_module.h
 */

#include <axis2_const.h>
#include <axis2_error.h>
#include <axis2_defines.h>
#include <axis2_env.h>
#include <axis2_allocator.h>
#include <axis2_string.h>
#include <axis2_conf.h>
#include <axis2_module_desc.h>
#include <axis2_hash.h>


#ifdef __cplusplus
extern "C"
{
#endif

    /** Type name for axis2_module_ops */
    typedef struct axis2_module_ops axis2_module_ops_t;
    /** Type name for axis2_module_ops */
    typedef struct axis2_module axis2_module_t;

    struct axis2_conf;

    struct axis2_module_ops
    {
        /**
         * Initializes module.
         * @param module pointer to module struct
         * @param env pointer to environment struct
         * @param conf_ctx pointer to configuration context
         * @param module_desc module description
         * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE 
         */
        axis2_status_t (AXIS2_CALL *
                init) (
                    axis2_module_t *module,
                    const axis2_env_t *env,
                    struct axis2_conf_ctx *conf_ctx,
                    axis2_module_desc_t *module_desc);

        /**
         * Shutdowns module.
         * @param module pointer to module struct
         * @param env pointer to environment struct
         * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE 
         */
        axis2_status_t (AXIS2_CALL *
                shutdown)(
                    axis2_module_t *module,
                    const axis2_env_t *env);

        /**
         * Fills the hash map of handler create functions for the module.
         * @param module pointer to module struct
         * @param env pointer to environment struct
         * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE 
         */        
        axis2_status_t (AXIS2_CALL *
                fill_handler_create_func_map)(
                    axis2_module_t *module,
                    const axis2_env_t *env);


    };

    /**
     * module struct.
     */
    struct axis2_module
    {
        /** operations of module */
        axis2_module_ops_t *ops;
        /** hash map of handler create functions */
        axis2_hash_t *handler_create_func_map;
    };

    /**
     * Creates module struct.
     * @param env pointer to environment struct
     * @return pointer to newly created module
     */
    AXIS2_EXTERN axis2_module_t * AXIS2_CALL
    axis2_module_create (
        const axis2_env_t *env);

/** Initializes module.
    @sa axis2_module_ops#init */
#define AXIS2_MODULE_INIT(module, env, conf_ctx, module_desc) \
      ((module)->ops->init (module, env, conf_ctx, module_desc))

/** Shutdowns module.
    @sa axis2_module_ops#shutdown */
#define AXIS2_MODULE_SHUTDOWN(module, env) \
      ((module)->ops->shutdown (module, env))

/** Fills handler create function map.
    @sa axis2_module_ops#fill_handler_create_func_map */    
#define AXIS2_MODULE_FILL_HANDLER_CREATE_FUNC_MAP(module, env) \
      ((module)->ops->fill_handler_create_func_map (module, env))

/** @} */

#ifdef __cplusplus
}
#endif
#endif /* AXIS2_MODULE_H */
