/*
 * 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
 */
 
#define DEFAULT_ENCODING "ISO-8859-1"

#include "repository.h"
#include "stringbuffer.h"

#include <stdio.h>
#include <string.h>
#include <libxml/encoding.h>


void jasperserver_print_resource_descriptor(jasperserver_resource_descriptor_t *rd, int depth);
void jasperserver_print_resource_property(jasperserver_resource_property_t *rp, int depth);
void jasperserver_print_parameter(jasperserver_parameter_t *rp, int depth);

/*
 This function free a list using a callback to function to correctly free the specific node type.
*/
void jasperserver_list_free(jasperserver_list_t *list, void (*freeFunc)(void *) )
{
          if (!list) return;
          jasperserver_list_free(list->next, freeFunc);
          //printf("Freeing node %x\n", list);
          //fflush(stdout);
          (*freeFunc)(list);
}


jasperserver_request_t * jasperserver_request_new()
{
     jasperserver_request_t *request = (jasperserver_request_t *)malloc(sizeof(jasperserver_request_t));
     jasperserver_string_t *operationName;
     jasperserver_string_t *language;
     
     operationName = jasperserver_string_new();
     jasperserver_string_cappend(operationName, JS_OPERATION_LIST );
     
     language = jasperserver_string_new();
     jasperserver_string_cappend(language, "en" );
     
     request->resource = 0;
     request->opertation = operationName;
     request->locale = language;
     request->arguments = 0;     
     
     return request;
}


void jasperserver_request_free(jasperserver_request_t *request)
{
     if (request->opertation) 
     { 
       jasperserver_string_free(request->opertation);
     }
     
     if (request->locale)
     {
       jasperserver_string_free(request->locale);
     }
     
     if (request->arguments)
     { 
        jasperserver_list_free( (jasperserver_list_t *)request->arguments, jasperserver_argument_free);
     }
     
     if (request->resource)
     {
        jasperserver_resource_descriptor_free( request->resource);
     }
     
     free(request);
}



jasperserver_argument_t * jasperserver_argument_new()
{
     jasperserver_argument_t *argument = (jasperserver_argument_t *)malloc(sizeof(jasperserver_argument_t));
     jasperserver_string_t *name;
     jasperserver_string_t *value;
     
     argument->next = NULL;
     argument->isListItem = 0;
     
     name = jasperserver_string_new();
     jasperserver_string_cappend(name, "" );
     argument->name = name;
     
     value = jasperserver_string_new();
     jasperserver_string_cappend(value, "" );
     argument->value = value;
     
     return argument;
}


void jasperserver_argument_free(void *argument_ptr)
{
     jasperserver_argument_t *argument;
     argument = argument_ptr;
     
     if (argument->name)
     {
        jasperserver_string_free(argument->name);
     }
     
     if (argument->value)
     {
        jasperserver_string_free(argument->value);
     }
     
     free(argument);
}


jasperserver_resource_descriptor_t * jasperserver_resource_descriptor_new()
{
     jasperserver_resource_descriptor_t *res = (jasperserver_resource_descriptor_t *)malloc(sizeof(jasperserver_resource_descriptor_t));
     jasperserver_string_t *name, *label, *description, *wsType, *uriString;
     
     res->next = NULL;
     res->isNew = 0;
     
     res->parameters = NULL;
     res->properties = NULL;
     res->children = NULL;
     
     name = jasperserver_string_new();
     jasperserver_string_cappend(name, "newfolder" );
     res->name = name;
     
     label = jasperserver_string_new();
     jasperserver_string_cappend(label, "newfolder" );
     res->label = label;
     
     description = jasperserver_string_new();
     jasperserver_string_cset(description, "" );
     res->description = description;
     
     wsType = jasperserver_string_new();
     jasperserver_string_cset(wsType, "" );
     res->wsType = wsType;
     
     uriString = jasperserver_string_new();
     jasperserver_string_cappend(uriString, "/" );
     res->uriString = uriString;
     
     return res;
}


void jasperserver_resource_descriptor_free(void *res_ptr)
{
     jasperserver_resource_descriptor_t *res;
     res = (jasperserver_resource_descriptor_t *)res_ptr;
     
     // Free the strings
     if (res->name) {jasperserver_string_free(res->name); }
     if (res->label) {jasperserver_string_free(res->label); }
     if (res->description) {jasperserver_string_free(res->description); }
     if (res->wsType) {jasperserver_string_free(res->wsType); }
     if (res->uriString) {jasperserver_string_free(res->uriString); }
     
     // Free the lists...
     if (res->properties) { 
        //printf("Free properties...\n");
        //fflush(stdout);
        jasperserver_list_free((jasperserver_list_t *)res->properties, jasperserver_resource_property_free); 
        res->properties=NULL;
     }
     
     if (res->children) { 
        //printf("Free resources...\n");
        //fflush(stdout);
        jasperserver_list_free((jasperserver_list_t *)res->children, jasperserver_resource_descriptor_free);
        res->children = NULL;
     }
     
     if (res->parameters) { 
        jasperserver_parameter_t *par = NULL;
        jasperserver_list_free((jasperserver_list_t *)res->parameters, jasperserver_parameter_free);
        res->parameters = NULL;
     }
     
     free(res);
}




jasperserver_resource_property_t * jasperserver_resource_property_new()
{
     jasperserver_resource_property_t *resp = (jasperserver_resource_property_t *)malloc(sizeof(jasperserver_resource_property_t));
     jasperserver_string_t *name;
     jasperserver_string_t *value;
     
     resp->next = NULL;
     resp->properties = NULL;
     
     name = jasperserver_string_new();
     jasperserver_string_cappend(name, "" );
     resp->name = name;
     
     value = jasperserver_string_new();
     jasperserver_string_cappend(value, "" );
     resp->value = value;
     
     return resp;
}


void jasperserver_resource_property_free(void *resp_ptr)
{
     jasperserver_resource_property_t *resp;
     resp = (jasperserver_resource_property_t *)resp_ptr;
     
     if (resp->name)
     {
        jasperserver_string_free(resp->name);
     }
     
     if (resp->value)
     {
        jasperserver_string_free(resp->value);
     }
     
     if (resp->properties) { 
           jasperserver_list_free((jasperserver_list_t *)resp->properties, jasperserver_resource_property_free);
           resp->properties=NULL;
     }
     
     free(resp);
}


jasperserver_parameter_t *jasperserver_parameter_new()
{
     jasperserver_parameter_t *resp = (jasperserver_parameter_t *)jasperserver_argument_new();
     return resp;
}


void jasperserver_parameter_free(void *resp_ptr)
{
     jasperserver_argument_free(resp_ptr);
}



jasperserver_operation_result_t * jasperserver_operation_result_new()
{
     jasperserver_operation_result_t *operationResult = (jasperserver_operation_result_t *)malloc(sizeof(jasperserver_operation_result_t));
     jasperserver_string_t *returnMessage, *version;
     
     operationResult->returnCode = 0;
     operationResult->resources = NULL;
     
     returnMessage = jasperserver_string_new();
     jasperserver_string_cappend(returnMessage, "" );
     operationResult->returnMessage = returnMessage;
     
     version = jasperserver_string_new();
     jasperserver_string_cappend(version, "" );
     operationResult->version = version;
     
     return operationResult;
}


void jasperserver_operation_result_free(void *op_ptr)
{
     jasperserver_operation_result_t *resp;
     resp = (jasperserver_operation_result_t *)op_ptr;
     
     if (resp->returnMessage)
     {
        jasperserver_string_free(resp->returnMessage);
     }
     
     if (resp->version)
     {
        jasperserver_string_free(resp->version);
     }
     
     if (resp->resources) { 
           jasperserver_list_free((jasperserver_list_t *)resp->resources, jasperserver_resource_descriptor_free);
           resp->resources=NULL;
     }
     
     free(resp);
}



jasperserver_server_t * jasperserver_server_new()
{
     jasperserver_server_t *server = (jasperserver_server_t *)malloc(sizeof(jasperserver_server_t));
     jasperserver_string_t *url, *username, *password;

     url = jasperserver_string_new();
     jasperserver_string_cappend(url, "" );
     server->url = url;
     
     username = jasperserver_string_new();
     jasperserver_string_cappend(username, "" );
     server->username = username;
     
     password = jasperserver_string_new();
     jasperserver_string_cappend(password, "" );
     server->password = password;
     
     return server;
}


void jasperserver_server_free(void *op_ptr)
{
     jasperserver_server_t *resp;
     resp = (jasperserver_server_t *)op_ptr;
     
     if (resp->url)
     {
        jasperserver_string_free(resp->url);
     }
     
     if (resp->username)
     {
        jasperserver_string_free(resp->username);
     }
     
     if (resp->password)
     {
        jasperserver_string_free(resp->password);
     }
     
     free(resp);
}


void jasperserver_list_append( jasperserver_list_t **list, jasperserver_list_t *node)
{
     jasperserver_list_t *current_node = NULL;
     
     if (*list == NULL)
     {
        *list = node;
     }
     else
     {
         current_node = *list;
         while (current_node->next)
         {
               current_node = current_node->next;
         }
         current_node->next = node;
     }
}


void jasperserver_print_resource_descriptor(jasperserver_resource_descriptor_t *rd, int depth)
{   
          int i=0;
          jasperserver_resource_property_t *property = NULL;
          jasperserver_resource_descriptor_t *resource = NULL;
          jasperserver_parameter_t *parameter = NULL;
          
          if (!rd) return;
          for (i=0; i<depth; ++i) printf("  ");
          printf("resourceDescriptor (%s,%s,%s)\n", JS_UTFSTR(rd->name), JS_UTFSTR(rd->label), JS_UTFSTR(rd->description)); 
          
          for (property = rd->properties; property; property = property->next)
          {
              jasperserver_print_resource_property(property, depth+1);
          }
          
          for (resource = rd->children; resource; resource = resource->next)
          {
              jasperserver_print_resource_descriptor(resource, depth+1);
          }
          
          for (parameter = rd->parameters; parameter; parameter = parameter->next)
          {
              jasperserver_print_parameter(parameter, depth+1);
          }
          
}

void jasperserver_print_resource_property(jasperserver_resource_property_t *rp, int depth)
{
          int i=0;
          jasperserver_resource_property_t *subProperty = NULL;
          
          if (!rp) return;
          for (i=0; i<depth; ++i) printf("  ");
          printf("resourceProperty (%s,%s)\n", JS_UTFSTR(rp->name), JS_UTFSTR(rp->value)); 
          
          for (subProperty = rp->properties; subProperty; subProperty = subProperty->next)
          {
              jasperserver_print_resource_property(subProperty, depth+1);
          }
}

void jasperserver_print_parameter(jasperserver_parameter_t *p, int depth)
{
          int i=0;
          
          if (!p) return;
          for (i=0; i<depth; ++i) printf("  ");
          printf("Parameter (%s,%s)\n", JS_UTFSTR(p->name), JS_UTFSTR(p->value)); 
}


jasperserver_resource_property_t *jasperserver_get_property(jasperserver_resource_descriptor_t *resource, char *propName)
{
   jasperserver_resource_property_t *prop = NULL;
   for (prop = resource->properties; prop; prop = prop->next )
   {
       if ( !strcmp( JS_UTFSTR(prop->name), propName ))
       {
            return prop;
       }
   }
   
   return NULL;
}


jasperserver_string_t *jasperserver_get_property_value(jasperserver_resource_descriptor_t *resource, char *propName)
{
   jasperserver_resource_property_t *prop = NULL;
   prop = jasperserver_get_property( resource, propName);
   if (prop) return prop->value;
   
   return NULL;
}
