/*
 * Copyright (C) 2007 JasperSoft http://www.jaspersoft.com
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed WITHOUT ANY WARRANTY; and without the 
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see http://www.gnu.org/licenses/gpl.txt 
 * or write to:
 * 
 * Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330,
 * Boston, MA  USA  02111-1307
 */

#ifndef jasperserver_repository_H
#define jasperserver_repository_H

#include "stringbuffer.h"

#define    	JS_TYPE_FOLDER  "folder"
#define    	JS_TYPE_REPORTUNIT  "reportUnit"
#define    	JS_TYPE_DATASOURCE  "datasource"
#define    	JS_TYPE_DATASOURCE_JDBC  "jdbc"
#define    	JS_TYPE_DATASOURCE_JNDI  "jndi"
#define    	JS_TYPE_DATASOURCE_BEAN  "bean"
#define    	JS_TYPE_IMAGE  "img"
#define    	JS_TYPE_FONT  "font"
#define    	JS_TYPE_JRXML  "jrxml"
#define    	JS_TYPE_CLASS_JAR  "jar"
#define    	JS_TYPE_RESOURCE_BUNDLE  "prop"
#define    	JS_TYPE_REFERENCE  "reference"
#define    	JS_TYPE_INPUT_CONTROL  "inputControl"
#define    	JS_TYPE_DATA_TYPE  "dataType"
#define    	JS_TYPE_OLAP_MONDRIAN_CONNECTION  "olapMondrianCon"
#define    	JS_TYPE_OLAP_XMLA_CONNECTION  "olapXmlaCon"
#define    	JS_TYPE_MONDRIAN_SCHEMA  "olapMondrianSchema"
#define    	JS_TYPE_XMLA_CONNTCTION  "xmlaConnection"
#define    	JS_TYPE_UNKNOW  "unknow"
#define    	JS_TYPE_LOV  "lov" // List of values...
#define    	JS_TYPE_QUERY  "query" // Query...
    
    
/**
 * These constants are copied here from DataType for facility
 */
#define    	JS_DT_TYPE_TEXT  1
#define    	JS_DT_TYPE_NUMBER  2
#define    	JS_DT_TYPE_DATE  3
#define    	JS_DT_TYPE_DATE_TIME  4 
    
/**
 * These constants are copied here from InputControl for facility
 */
#define    	JS_IC_TYPE_BOOLEAN  1
#define    	JS_IC_TYPE_SINGLE_VALUE  2
#define    	JS_IC_TYPE_SINGLE_SELECT_LIST_OF_VALUES  3
#define    	JS_IC_TYPE_SINGLE_SELECT_QUERY  4
#define    	JS_IC_TYPE_MULTI_VALUE  5
#define    	JS_IC_TYPE_MULTI_SELECT_LIST_OF_VALUES  6
#define    	JS_IC_TYPE_MULTI_SELECT_QUERY  7
    
#define    	JS_IC_TYPE_SINGLE_SELECT_LIST_OF_VALUES_RADIO  8
#define    	JS_IC_TYPE_SINGLE_SELECT_QUERY_RADIO  9
#define    	JS_IC_TYPE_MULTI_SELECT_LIST_OF_VALUES_CHECKBOX  10
#define    	JS_IC_TYPE_MULTI_SELECT_QUERY_CHECKBOX  11
    
#define    	JS_PROP_VERSION  "PROP_VERSION"
#define    	JS_PROP_PARENT_FOLDER  "PROP_PARENT_FOLDER"
#define    	JS_PROP_RESOURCE_TYPE  "PROP_RESOURCE_TYPE"
#define    	JS_PROP_CREATION_DATE  "PROP_CREATION_DATE"
#define    	JS_PROP_REFERENCE_URI  "PROP_REFERENCE_URI"

// File resource properties
#define    	JS_PROP_FILERESOURCE_HAS_DATA  "PROP_HAS_DATA"
#define    	JS_PROP_FILERESOURCE_IS_REFERENCE  "PROP_IS_REFERENCE"
#define    	JS_PROP_FILERESOURCE_REFERENCE_URI  "PROP_REFERENCE_URI"
#define    	JS_PROP_FILERESOURCE_WSTYPE  "PROP_WSTYPE"
    
// Datasource properties
#define    	JS_PROP_DATASOURCE_DRIVER_CLASS  "PROP_DATASOURCE_DRIVER_CLASS"
#define    	JS_PROP_DATASOURCE_CONNECTION_URL  "PROP_DATASOURCE_CONNECTION_URL"
#define    	JS_PROP_DATASOURCE_USERNAME  "PROP_DATASOURCE_USERNAME"
#define    	JS_PROP_DATASOURCE_PASSWORD  "PROP_DATASOURCE_PASSWORD"
#define    	JS_PROP_DATASOURCE_JNDI_NAME  "PROP_DATASOURCE_JNDI_NAME"
#define    	JS_PROP_DATASOURCE_BEAN_NAME  "PROP_DATASOURCE_BEAN_NAME"
#define    	JS_PROP_DATASOURCE_BEAN_METHOD  "PROP_DATASOURCE_BEAN_METHOD"
    
    
// ReportUnit resource properties
#define    	JS_PROP_RU_DATASOURCE_TYPE  "PROP_RU_DATASOURCE_TYPE"
#define    	JS_PROP_RU_IS_MAIN_REPORT  "PROP_RU_IS_MAIN_REPORT"
#define    	JS_PROP_RU_INPUTCONTROL_RENDERING_VIEW  "PROP_RU_INPUTCONTROL_RENDERING_VIEW"
#define    	JS_PROP_RU_REPORT_RENDERING_VIEW  "PROP_RU_REPORT_RENDERING_VIEW"
    
// DataType resource properties
#define    	JS_PROP_DATATYPE_STRICT_MAX  "PROP_DATATYPE_STRICT_MAX"
#define    	JS_PROP_DATATYPE_STRICT_MIN  "PROP_DATATYPE_STRICT_MIN"
#define    	JS_PROP_DATATYPE_MIN_VALUE  "PROP_DATATYPE_MIN_VALUE"
#define    	JS_PROP_DATATYPE_MAX_VALUE  "PROP_DATATYPE_MAX_VALUE"
#define    	JS_PROP_DATATYPE_PATTERN  "PROP_DATATYPE_PATTERN"
#define    	JS_PROP_DATATYPE_TYPE  "PROP_DATATYPE_TYPE"
    
 // ListOfValues resource properties
#define    	JS_PROP_LOV  "PROP_LOV"
#define    	JS_PROP_LOV_LABEL  "PROP_LOV_LABEL"
#define    	JS_PROP_LOV_VALUE  "PROP_LOV_VALUE"
    
    
// InputControl resource properties
#define    	JS_PROP_INPUTCONTROL_TYPE  "PROP_INPUTCONTROL_TYPE"
#define    	JS_PROP_INPUTCONTROL_IS_MANDATORY  "PROP_INPUTCONTROL_IS_MANDATORY"
#define    	JS_PROP_INPUTCONTROL_IS_READONLY  "PROP_INPUTCONTROL_IS_READONLY"
    
// SQL resource properties
#define    	JS_PROP_QUERY  "PROP_QUERY"
#define    	JS_PROP_QUERY_VISIBLE_COLUMNS  "PROP_QUERY_VISIBLE_COLUMNS"
#define    	JS_PROP_QUERY_VISIBLE_COLUMN_NAME  "PROP_QUERY_VISIBLE_COLUMN_NAME"
#define    	JS_PROP_QUERY_VALUE_COLUMN  "PROP_QUERY_VALUE_COLUMN"
#define    	JS_PROP_QUERY_LANGUAGE  "PROP_QUERY_LANGUAGE"
    
    
// SQL resource properties
#define    	JS_PROP_QUERY_DATA  "PROP_QUERY_DATA"
#define    	JS_PROP_QUERY_DATA_ROW  "PROP_QUERY_DATA_ROW"
#define    	JS_PROP_QUERY_DATA_ROW_COLUMN  "PROP_QUERY_DATA_ROW_COLUMN"
    
    
// OLAP XMLA Connection
#define    	JS_PROP_XMLA_URI  "PROP_XMLA_URI"
#define    	JS_PROP_XMLA_CATALOG  "PROP_XMLA_CATALOG"
#define    	JS_PROP_XMLA_DATASOURCE  "PROP_XMLA_DATASOURCE"
#define    	JS_PROP_XMLA_USERNAME  "PROP_XMLA_USERNAME"
#define    	JS_PROP_XMLA_PASSWORD  "PROP_XMLA_PASSWORD"

/* Argument constants */
#define    	JS_ARG_MODIFY_REPORTUNIT  "MODIFY_REPORTUNIT_URI"
#define    	JS_ARG_CREATE_REPORTUNIT  "CREATE_REPORTUNIT_BOOLEAN"
#define    	JS_ARG_LIST_DATASOURCES   "LIST_DATASOURCES"
#define    	JS_ARG_IC_GET_QUERY_DATA   "IC_GET_QUERY_DATA"
#define    	JS_ARG_VALUE_TRUE  "true"
#define    	JS_ARG_VALUE_FALSE  "false" 
#define    	JS_ARG_RUN_OUTPUT_FORMAT  "RUN_OUTPUT_FORMAT"
#define    	JS_ARG_RUN_OUTPUT_FORMAT_PDF  "PDF"
#define    	JS_ARG_RUN_OUTPUT_FORMAT_JRPRINT  "JRPRINT"
#define    	JS_ARG_RUN_OUTPUT_FORMAT_HTML  "HTML"
#define    	JS_ARG_RUN_OUTPUT_FORMAT_XLS  "XLS"
#define    	JS_ARG_RUN_OUTPUT_FORMAT_XML  "XML"
#define    	JS_ARG_RUN_OUTPUT_FORMAT_CSV  "CSV"
#define    	JS_ARG_RUN_OUTPUT_FORMAT_RTF  "RTF"
#define    	JS_ARG_RUN_OUTPUT_IMAGES_URI  "IMAGES_URI"
#define    	JS_ARG_RUN_OUTPUT_PAGE  "PAGE"

/* types of operations */
#define    	JS_OPERATION_RUN_REPORT  "runReport"
#define    	JS_OPERATION_LIST  "list"
#define    	JS_OPERATION_PUT  "put"
#define    	JS_OPERATION_GET  "get"
// #define 	   JS_OPERATION_LOGIN  "login"  // this operation is deprecated.
#define    	JS_OPERATION_CHECK_DEPENDS  "checkForDependentResources"


/** \struct jasperserver_server
    \brief  This struct is used to hold connection information.
    \typedef jasperserver_server_t
*/
typedef struct jasperserver_server
{
    jasperserver_string_t* url;                     /**< \brief url of the server */
    jasperserver_string_t* username;                /**< \brief username */
    jasperserver_string_t* password;                /**< \brief password */
} jasperserver_server_t;


/** \struct jasperserver_resource
    \brief  This struct is used to store a resource property.
    \typedef jasperserver_resource_property_t
*/
typedef struct jasperserver_resource_property
{
   struct jasperserver_resource_property *next;  /**< Pointer to the next property */
   jasperserver_string_t* name;                     /**< Property name */
   jasperserver_string_t* value;                    /**< Property value */
   struct jasperserver_resource_property *properties;     /***<Pointer to the first child ResourceProperty (NULL means no children are available) */
} jasperserver_resource_property_t;

/** \struct jasperserver_parameter
    \brief  This struct is used to store a porameter.
    \typedef jasperserver_parameter_t
*/
typedef struct jasperserver_parameter
{
   struct jasperserver_parameter *next;  /**< Pointer to the next parameter */
   jasperserver_string_t* name;                /**< Property name */
   jasperserver_string_t* value;               /**< Property value */
   int   isListItem;          /**< list of items flag */
} jasperserver_parameter_t;

/**  jasperserver_list_item_t stores informations about a list item.
     The type derives from the parameter struct
     
     \see jasperserver_parameter_t
*/
typedef jasperserver_parameter_t jasperserver_list_item_t;

/**  jasperserver_argument_t stores informations about an argument for a request.
     The type derives from the parameter struct
     
     \see jasperserver_parameter_t
*/
typedef jasperserver_parameter_t jasperserver_argument_t;

/** \struct jasperserver_resource_descriptor
    \brief  This struct is used to store a resource_descriptor.
    \typedef jasperserver_resource_descriptor_t
*/
typedef struct jasperserver_resource_descriptor
{
    struct jasperserver_resource_descriptor *next;    /**< Pointer to the next resourec */
    jasperserver_string_t* name;                     /**< Resource name */
    jasperserver_string_t* label;                    /**< Resource label */
    jasperserver_string_t* description;              /**< Resource description */
    int   isNew;                      /**< Is it a new resoure (used to create a new resource) */
    jasperserver_string_t* wsType;                   /**< Type of the resource */
    jasperserver_string_t* uriString;                /**< URI of the resource inside the repository */
    
    struct jasperserver_resource_property *properties;     /**< Pointer to the first jasperserver_resource_property_t (NULL means no properties are available) */
    struct jasperserver_resource_descriptor *children; /**< Pointer to the first child (NULL means no parameters are available) */
    struct jasperserver_parameter *parameters;     /**< Pointer to the first parameter (NULL means no parameters are available) */
} jasperserver_resource_descriptor_t;

/** \struct jasperserver_request
    \brief  This struct is used to store a request.
    \typedef jasperserver_request_t
*/
typedef struct jasperserver_request
{
   jasperserver_resource_descriptor_t *resource;    /**< Request resource descriptor */
   jasperserver_string_t* opertation;                         /**< Operation name */
   jasperserver_string_t* locale;                             /**< A string defining locale (like en or en_US) */
   jasperserver_argument_t *arguments;                    /**< Request arguments */
} jasperserver_request_t;

/** \struct jasperserver_operation_result
    \brief  This struct is used to store the result of a service execution.
    \typedef jasperserver_request_t
*/
typedef struct jasperserver_operation_result
{ 
   int returnCode;                           /**< Operation result return code */
   jasperserver_string_t* returnMessage;                      /**< An optional return message */
   jasperserver_string_t* version;                            /**< the version of the contacted JasperServer  */
   jasperserver_resource_descriptor_t *resources;   /**< List of resources (0 or more)*/
} jasperserver_operation_result_t;


/** \struct jasperserver_list
    \brief  This structure is used to cast other struct having a next field
     as first pointer.
    \typedef jasperserver_list_t
    
    \see jasperserver_list_append, jasperserver_list_free
*/
typedef struct jasperserver_list
{
  struct jasperserver_list *next;        
} jasperserver_list_t;

/** \brief  Append node at the end of the list pointed by list
    
    jasperserver_list_append takes the pointer to a pointer of the first element of a list.
    If traverse the list up to the end, and add the new node updating the field 'next' of the previous node.
    
    \param list It is a pointer to a pointer of a list
    \param node the element to append
        
*/
void jasperserver_list_append( jasperserver_list_t **list, jasperserver_list_t *node);

/** \brief  This is a quick way to free an entire list of elements
    
    jasperserver_list_free takes a pointer to list and call itself on list->next.
    Each node is freed using the function passed. Example:
    \code
    jasperserver_list_free( (jasperserver_list_t *)request->arguments, jasperserver_argument_free);
    \endcode
    
    \param list It is a pointer to a list
    \param freeFunc the address of the function to use to free each node
        
*/
void jasperserver_list_free(jasperserver_list_t *list, void (*freeFunc)(void *) );

/** \brief  Instance a new request
    
    This function initializes the request. The resource field is set to NULL,
    the operation is set to OPERATION_LIST, locale is set to "en" and arguments to NULL.
    
    It is responsability of the user  free the memory allocated by this function
    using jasperserver_request_free()
    
    \return a pointer to a new request
    
    \see jasperserver_request_free()
        
*/
jasperserver_request_t * jasperserver_request_new();

/** \brief  Free a request
    
    Free the memory allocated using jasperserver_request_new.
    
    This method frees recursively all the elements of the request and relative lists.
    
    \param request The request to free
    
    \see jasperserver_request_new()
        
*/
void jasperserver_request_free(jasperserver_request_t *request); 

/** \brief  Instance a new argument
    
    This function initializes the argument.
    
    It is responsability of the user  free the memory allocated by this function
    using jasperserver_argument_free()
    
    \return a pointer to a new argument
    
    \see jasperserver_argument_free()
        
*/
jasperserver_argument_t *jasperserver_argument_new();

/** \brief  Free an argument
    
    Free the memory allocated using jasperserver_argument_new.
    
    \param argument The argument to free (jasperserver_argument_t * assumed)
    
    \see jasperserver_argument_new()
        
*/
void jasperserver_argument_free(void *argument); // 

/** \brief  Instance a new resource_descriptor
    
    This function initializes the resource_descriptor.
    
    It is responsability of the user  free the memory allocated by this function
    using jasperserver_resource_descriptor_free()
    
    \return a pointer to a new resource_descriptor
    
    \see jasperserver_resource_descriptor_free()
        
*/
jasperserver_resource_descriptor_t *jasperserver_resource_descriptor_new();

/** \brief  Free a resource_descriptor
    
    Free the memory allocated using jasperserver_resource_descriptor_new.
    
    This method frees recursively all the elements of the resource_descriptor and relative lists.
    
    \param resource_descriptor The resource_descriptor to free (jasperserver_resource_descriptor_t * assumed)
    
    \see jasperserver_resource_descriptor_new()
        
*/
void jasperserver_resource_descriptor_free(void *resource_descriptor);

/** \brief  Instance a new resource_property
    
    This function initializes the resource_property.
    
    It is responsability of the user  free the memory allocated by this function
    using jasperserver_resource_property_free()
    
    \return a pointer to a new resource_property
    
    \see jasperserver_resource_property_free()
        
*/
jasperserver_resource_property_t * jasperserver_resource_property_new();

/** \brief  Free a resource_property
    
    Free the memory allocated using jasperserver_resource_property_new.
    
    This method frees recursively all the elements of the resource_property and relative lists.
    
    \param resource_property The resource_property to free (jasperserver_resource_property_t* assumed)
    
    \see jasperserver_resource_property_new()
        
*/
void jasperserver_resource_property_free(void *resource_property); 

/** \brief  Instance a new parameter
    
    This function initializes the parameter.
    
    It is responsability of the user  free the memory allocated by this function
    using jasperserver_parameter_free()
    
    \return a pointer to a new parameter
    
    \see jasperserver_parameter_free()
        
*/
jasperserver_parameter_t * jasperserver_parameter_new();

/** \brief  Free a parameter
    
    Free the memory allocated using jasperserver_parameter_new.
    
    This method frees recursively all the elements of the parameter and relative lists.
    
    \param parameter The parameter to free (jasperserver_parameter_t* assumed)
    
    \see jasperserver_parameter_new()
        
*/
void jasperserver_parameter_free(void *parameter); // jasperserver_parameter_t * assumed

/** \brief  Instance a new operation_result
    
    This function initializes the operation_result.
    
    It is responsability of the user  free the memory allocated by this function
    using jasperserver_operation_result_free()
    
    \return a pointer to a new operation_result
    
    \see jasperserver_operation_result_free()
        
*/
jasperserver_operation_result_t * jasperserver_operation_result_new();

/** \brief  Free a operation_result
    
    Free the memory allocated using jasperserver_operation_result_new.
    
    This method frees recursively all the elements of the operation_result and relative lists.
    
    \param operation_result The operation_result to free (jasperserver_operation_result_t* assumed)
    
    \see jasperserver_operation_result_new()
        
*/
void jasperserver_operation_result_free(void *op_ptr);

/** \brief  Instance a new server
    
    This function initializes the server.
    
    It is responsability of the user  free the memory allocated by this function
    using jasperserver_server_free()
    
    \return a pointer to a new server
    
    \see jasperserver_server_free()
        
*/
jasperserver_server_t * jasperserver_server_new();
void jasperserver_server_free(void *op_ptr);

/** \brief  Print a resource descriptor
    
    Useful to debug.    
    
    \param rd A valid resource descriptor
    \param depth Spaces to add on the start of the line
        
*/
void jasperserver_print_resource_descriptor(jasperserver_resource_descriptor_t *rd, int depth);


/** \brief Get the value of a property with name 'propName' from the resource 'resource'
*  This funciont looks inside the resource descriptor passed as first parameter for a parameter called 'propName'
*  and if found, return the property value.
*
*  \param resource The resource in which look for the property
*  \param propName The name of the property to look for
*  \return The value of the property or NULL if a property with such name is not found.
*  \warning Since the value of the property returned belongs to the parent resource, DO NOT free the property value by yourself.
*
*  \see jasperserver_get_property()
*/
jasperserver_string_t *jasperserver_get_property_value(jasperserver_resource_descriptor_t *resource, char *propName);

/** \brief Get a property with name 'propName' from the resource 'resource'
*  This funciont looks inside the resource descriptor passed as first parameter for a parameter called 'propName'
*
*  \param inputcontrol The resource in which look for the property
*  \param propName The name of the property to look for
*  \return The found property or NULL if a property with such name is not found.
*  \warning Since the property returned belongs to the parent resource, DO NOT free the property by yourself.
*
*  \see jasperserver_get_property_value()
*/
jasperserver_resource_property_t *jasperserver_get_property(jasperserver_resource_descriptor_t *resource, char *propName);
#endif
