/*
 * Portions of this file Copyright 1999-2005 University of Chicago
 * Portions of this file Copyright 1999-2005 The University of Southern California.
 *
 * This file or a portion of this file is licensed under the
 * terms of the Globus Toolkit Public License, found at
 * http://www.globus.org/toolkit/download/license.html.
 * If you redistribute this file, with or without
 * modifications, you must include this notice in the file.
 */


#ifndef _GLOBUS_HANDLER_H_
#define _GLOBUS_HANDLER_H_

#include "globus_common.h"

EXTERN_C_BEGIN

extern globus_module_descriptor_t       globus_i_handler_module;
#define GLOBUS_HANDLER_MODULE           &globus_i_handler_module

extern globus_extension_registry_t      globus_handler_registry;
#define GLOBUS_HANDLER_REGISTRY         &globus_handler_registry

typedef struct globus_handler_chain_s * globus_handler_chain_t;

typedef struct globus_handler_session_descriptor_s *
                                      globus_handler_session_descriptor_t;

typedef enum
{
    GLOBUS_HANDLER_TYPE_REQUEST_INIT         = 0x0001,
    GLOBUS_HANDLER_TYPE_REQUEST              = 0x0002,
    GLOBUS_HANDLER_TYPE_REQUEST_DESTROY      = 0x0004,
    GLOBUS_HANDLER_TYPE_REQUEST_ALL          = 0x000F,
    GLOBUS_HANDLER_TYPE_RESPONSE_INIT        = 0x0010,
    GLOBUS_HANDLER_TYPE_RESPONSE             = 0x0020,
    GLOBUS_HANDLER_TYPE_RESPONSE_DESTROY     = 0x0040,
    GLOBUS_HANDLER_TYPE_RESPONSE_ALL         = 0x00F0,
    GLOBUS_HANDLER_TYPE_ALL                  = 0x00FF
} globus_handler_type_t;

enum
{
    GLOBUS_HANDLER_ERROR_REGISTRY_LOOKUP_FAILED = 1024,
    GLOBUS_HANDLER_ERROR_HEADER_ELEMENT_NOT_FOUND,
    GLOBUS_HANDLER_ERROR_DEFAULT_TRIGGER_ALREADY_DEFINED,
    GLOBUS_HANDLER_ERROR_NO_TRIGGERS_DEFINED
};

#define GLOBUS_HANDLER_STATUS_NOT_TRIGGERED 0xFFFFFFF0

#define GlobusHandlerStatusNotTriggeredCheck(_STATUS_) \
    (_STATUS_ == GLOBUS_HANDLER_STATUS_NOT_TRIGGERED)

#include "globus_soap_message_handle.h"

typedef void (* globus_handler_invoke_func_t) (
    globus_handler_session_descriptor_t session,
    globus_soap_message_handle_t        message,
    globus_result_t                     result);

typedef void (* globus_handler_callback_func_t) (
    globus_result_t                     result,
    void *                              callback_args);

typedef struct globus_handler_trigger_s
{
    xsd_QName *                         element;
    globus_handler_invoke_func_t        invoke;
} globus_handler_trigger_t;

typedef struct globus_handler_descriptor_s
{
    globus_handler_invoke_func_t        request_init;
    globus_handler_invoke_func_t        request;
    globus_handler_invoke_func_t        request_destroy;
    globus_handler_invoke_func_t        response_init;
    globus_handler_invoke_func_t        response;
    globus_handler_invoke_func_t        response_destroy;
    globus_list_t *                     trigger_list;
    globus_handler_invoke_func_t        default_trigger;
} globus_handler_descriptor_t;

globus_result_t
globus_handler_chain_init(
    globus_handler_chain_t *            chain);

globus_result_t
globus_handler_chain_copy(
    globus_handler_chain_t *            dest,
    globus_handler_chain_t              src);

globus_result_t
globus_handler_chain_push(
    globus_handler_chain_t              chain,
    globus_handler_type_t               type,
    const char *                        handler_endpoint);

void
globus_handler_chain_destroy(
    globus_handler_chain_t              chain);

void
globus_handler_finished(
    globus_handler_session_descriptor_t session,
    globus_result_t                     result);

void
globus_handler_chain_register_invoke(
    globus_handler_chain_t              chain,
    globus_handler_type_t               type,
    globus_soap_message_handle_t        message,
    globus_handler_callback_func_t      callback,
    void *                              user_args);

globus_bool_t
globus_handler_chain_has_trigger(
    globus_handler_chain_t              chain,
    const xsd_QName *                   element);

globus_result_t
globus_handler_chain_register_trigger(
    globus_handler_chain_t              chain,
    globus_soap_message_handle_t        message,
    const xsd_QName *                   element,
    globus_handler_callback_func_t      callback,
    void *                              user_args);

EXTERN_C_END

#endif
