/*
 * 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_ENV_H
#define AXIS2_ENV_H

/**
 * @file axis2_env.h
 * @brief Axis2 environment that acts as a container for error, log and memory 
 *  allocator routines
 */

#include <axis2_allocator.h>
#include <axis2_error.h>
#include <axis2_log.h>
#include <axis2_thread_pool.h>

#ifdef __cplusplus
extern "C"
{
#endif

/** @defgroup axis2_util Axis2 utilities
  * @ingroup axis2
  * @{
  */

/** @} */

    struct axis2_environment;
    struct axis2_environment_ops;

/**
 * @defgroup axis2_environment Environment Container
 * @ingroup axis2_util 
 * @{
 */

  /** 
    * \brief Axis2 Environment struct
    *
    * Environment acts as a container for error, log, memory allocator and other
    * routines
    */
    typedef struct axis2_environment
    {
        /** Memory allocation routines */
        axis2_allocator_t *allocator;
        /** Error handling */
        axis2_error_t *error;
        /** Logging routines */
        axis2_log_t *log;
		/** This flag indicate whether logging is enabled or not */
		axis2_bool_t log_enabled;
		/** Thread pooling routines */
		axis2_thread_pool_t *thread_pool;
    } axis2_env_t;

	/**
    * Creates an environment struct. Users of axis2 should not use this function
	* to create an environment. He should use the other two create functions.
    * @param allocator pointer to an instance of allocator struct. Must be non-NULL    
    * @return pointer to the newly created environment struct 
    */
    AXIS2_DECLARE(axis2_env_t *) axis2_env_create (axis2_allocator_t
                                                   *allocator);                                                   
	
  /**
    * Creates an environment struct
    * @param allocator pointer to an instance of allocator struct. Must be non-NULL
    * @param error pointer to an instance of error struct. Must be non-NULL.
    * it would be taken as a flag for no logging.    
    * @return pointer to the newly created environment struct 
    */
    AXIS2_DECLARE(axis2_env_t *) axis2_env_create_with_error 
													(axis2_allocator_t *allocator
                                                   , axis2_error_t *error);
	
	/**
    * Creates an environment struct
    * @param allocator pointer to an instance of allocator struct. Must be non-NULL
    * @param error pointer to an instance of error struct. Must be non-NULL.
    * @param log pointer to an instance of log struct. May be NULL. If NULL
    * it would be taken as a flag for no logging.    
    * @return pointer to the newly created environment struct 
    */
    AXIS2_DECLARE(axis2_env_t *) axis2_env_create_with_error_log 
													(axis2_allocator_t *allocator
                                                   , axis2_error_t *error
                                                   , axis2_log_t *log);
												   
		/**
    * Creates an environment struct
    * @param allocator pointer to an instance of allocator struct. Must be non-NULL
    * @param error pointer to an instance of error struct. Must be non-NULL.
    * @param log pointer to an instance of log struct. May be NULL. If NULL
    * it would be taken as a flag for no logging.
	* @param pool pointer to an instance of thread_pool. May be NULL. If NULL
    * @return pointer to the newly created environment struct 
    */
    AXIS2_DECLARE(axis2_env_t *) axis2_env_create_with_error_log_thread_pool 
													(axis2_allocator_t *allocator
                                                   , axis2_error_t *error
                                                   , axis2_log_t *log
												   , axis2_thread_pool_t *pool);

  /**
    * Creates an environment struct
    * @param allocator pointer to an instance of allocator struct. Mandatory, cannot be NULL
    * @param error pointer to an instance of error struct. Optional, can be NULL. If NULL default error handler would be used.
    * @param log pointer to an instance of log struct. Optional, can be NULL. If NULL default log handler would be used.
    * @param string pointer to an instance of string struct. Optional, can be NULL. If NULL default string handler would be used.
    * @return pointer to the newly created environment struct 
    */
    AXIS2_DECLARE(axis2_status_t) axis2_env_free (axis2_env_t *env);
    
    /**
     * Enables logging
     */
    AXIS2_DECLARE(axis2_status_t) axis2_env_enable_log (axis2_env_t **env, axis2_bool_t enable);

    /**
      * Checks the status code of environment
      */
    AXIS2_DECLARE(axis2_status_t) axis2_env_check_status (axis2_env_t **env);
    
    /**
      * Writes given message to the log
      */
    AXIS2_DECLARE(axis2_status_t) axis2_env_write_log (axis2_env_t **env, const char* message, axis2_log_levels_t level);
    #define AXIS2_LOG(env, message, level) axis2_env_write_log (env,message, level)

    #define AXIS2_ENV_CHECK(env, error_return) \
    if(!env || !(*env))  \
	{ \
		axis2_allocator_t *allocator = axis2_allocator_init (NULL); \
        *env = axis2_env_create (allocator); \
		AXIS2_ERROR_SET_STATUS_CODE((*env)->error, AXIS2_CRTICAL_FAILURE);  \
		AXIS2_ERROR_SET_ERROR_NUMBER((*env)->error, \
		        AXIS2_ERROR_ENVIRONMENT_IS_NULL); \
		return error_return; \
	} \
    else \
    { \
        AXIS2_ERROR_SET_STATUS_CODE((*env)->error, AXIS2_SUCCESS); \
    }
    

/** @} */



    





#ifdef __cplusplus
}
#endif

#endif                          /* AXIS2_ENV_H */
