/* sunone-message.c
 *
 * Copyright (C) 2002-2004 Sun Microsystems, Inc
 *
 * AUTHORS
 *     Jack Jia <jack.jia@sun.com>
 *     Harry Lu <harry.lu@sun.com>
 *     Alfred Peng <alfred.peng@sun.com>
 *     Rodrigo Moya <rodrigo@ximian.com>
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>
#include <string.h>
#include <libecal/e-cal-component.h>
#include "sunone-util.h"
#include "sunone-message.h"

gboolean jescs_verbose_debug = FALSE;
gboolean jescs_long_debug = FALSE;
#define RESPONSE_MAX_LENGTH 65535

void sunone_message_init () 
{
	if (getenv ("EVOLUTION_JESCS_VERBOSE_DEBUG"))
		jescs_verbose_debug = TRUE;
	if (getenv ("EVOLUTION_JESCS_LONG_DEBUG"))
		jescs_long_debug = TRUE;

}

SoupMessage *
sunone_message_new_from_uri (SoupUri *suri, const char *method)
{
	SoupMessage *msg;

	g_return_val_if_fail (suri != NULL, NULL);

	msg = soup_message_new_from_uri (method, suri);

	return msg;
}

SoupMessage *
sunone_message_new_full_from_uri (SoupUri *suri, const char *method,
					const char *content_type,
				  	SoupOwnership owner, char *body,
				  	gulong length)
{
	SoupMessage *msg;

	g_return_val_if_fail (suri != NULL, NULL);

	msg = soup_message_new_from_uri (method, suri);
	soup_message_set_request (msg, content_type, owner, body, length);

	return msg;
}

#ifdef SUNONE_DEBUG
static void
print_header (gpointer name, gpointer value, gpointer data)
{
	printf ("%s: %s\n", (char *) name, (char *) value);
}

static void
sunone_debug_handler (SoupMessage *msg, gpointer user_data)
{
	if (jescs_verbose_debug) {
		printf ("%d %s (%p @ %lu)\n", msg->status_code, msg->reason_phrase,
			msg, time (0));
		soup_message_foreach_header (msg->response_headers,
					     print_header, NULL);
		if (msg->response.length &&
		    SUNONE_ERROR_IS_SUCCESSFUL (msg->status_code)) {
			if (jescs_long_debug) {
				printf ("\n%.*s\n", (int) msg->response.length,
					msg->response.body);
			} else {
			    	if (msg->response.length < RESPONSE_MAX_LENGTH)
					printf ("\n%.*s\n", (int) msg->response.length,
						msg->response.body);
			    	else 
			    		printf ("\n%.*s\n", RESPONSE_MAX_LENGTH,
						msg->response.body);
			}
		}
		printf ("\n");
	}
}
#endif

void
setup_message (SoupMessage *msg)
{
	soup_message_add_header (msg->request_headers, "User-Agent",
				 "Evolution/" EVOLUTION_VERSION);

#ifdef SUNONE_DEBUG
	if (jescs_verbose_debug)
	{
		const SoupUri *uri = soup_message_get_uri (msg);

		printf ("%s %s%s%s HTTP/1.1 (%p @ %lu)\n",
			msg->method, uri->path,
			uri->query ? "?" : "",
			uri->query ? uri->query : "",
			msg, (unsigned long)time (0));
		soup_message_foreach_header (msg->request_headers,
					     print_header, NULL);
		if (msg->request.length) {
			printf ("\n%.*s\n", (int)msg->request.length,
				msg->request.body);
		}
		printf ("\n");

		soup_message_add_handler (msg, SOUP_HANDLER_POST_BODY,
					  sunone_debug_handler, NULL);
	}
#endif
}

void
parse_server_response (SoupMessage *msg, SoupStatusClass *error_class)
{
	icalcomponent *icalcomp;
	icalproperty *icalprop;

	if (!msg->response.body)
		return;

	icalcomp = sunone_util_icalparser_parse_string (msg->response.body, msg->response.length);
	if (icalcomp) {
		icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
		while (icalprop) {
			const char *x_name, *x_val;

			x_name = icalproperty_get_x_name (icalprop);
			x_val = icalproperty_get_x (icalprop);

			if (!strcmp (x_name, "X-NSCP-WCAP-ERRNO")) {
				gint ival = atoi (x_val);

				if (ival == -1) {
					soup_message_set_status_full (msg, SUNONE_ERROR_LOGOUT_SUCCESSFUL,
								     "Logout has been successful");
				} else if (ival == 0) {
					soup_message_set_status_full (msg, SUNONE_ERROR_COMMAND_SUCCESSFUL,
								     "Command successful");
				} else if (ival == 1) {
					soup_message_set_status_full (msg, SUNONE_ERROR_LOGIN_FAILED,
								     "Login failed");
				} else if (ival == 2) {
					soup_message_set_status_full (msg, SUNONE_ERROR_LOGIN_OK_DEFAULT_CALENDAR_NOT_FOUND,
								     "Login ok, but default calendar not found");
				} else if ((ival >= 3 && ival <= 24) || ival == 26 ||
					   ival == 27 || ival == 36 || ival == 39 ||
					   ival == 41 || ival == 42 || 
					   ival == 55 || ival == 56 || ival == 61 ||
					   ival == 62 || ival == 63 || ival == 64 ||
					   ival == 65 || ival == 66) {
					soup_message_set_status_full (msg, SUNONE_ERROR_COMMAND_FAILED,
								     "Command failed");
				} else if (ival == 25) {
					soup_message_set_status_full (msg, SUNONE_ERROR_CALENDAR_ALREADY_EXISTS,
								     "Calendar already exists");
				} else if (ival == 28 || ival == 44 || ival == 76) {
					soup_message_set_status_full (msg, SUNONE_ERROR_ACCESS_DENIED,
								     "Access denied");
				} else if (ival == 29) {
					soup_message_set_status_full (msg, SUNONE_ERROR_CALENDAR_DOES_NOT_EXIST,
								     "Calendar does not exist");
				} else if (ival == 30) {
					soup_message_set_status_full (msg, SUNONE_ERROR_ILLEGAL_CALID_NAME,
								     "Illegal calendar ID name");
				} else if (ival == 31 || ival == 32) {
					soup_message_set_status_full (msg, SUNONE_ERROR_CANNOT_MODIFY_LINKED_OBJECTS,
								     "Cannot modify linked objects");
				} else if (ival == 33) {
					soup_message_set_status_full (msg, SUNONE_ERROR_CANNOT_SEND_MAIL,
								     "Cannot send mail");
				} else if (ival == 34) {
					soup_message_set_status_full (msg, SUNONE_ERROR_CALENDAR_DISABLED,
								     "Calendar disabled");
				} else if (ival == 35) {
					soup_message_set_status_full (msg, SUNONE_ERROR_WRITE_IMPORT_FAILED,
								     "Write import failed");
				} else if (ival == 37) {
					soup_message_set_status_full (msg, SUNONE_ERROR_CAPI_NOT_SUPPORTED,
								     "CAPI not supported");
				} else if (ival == 38) {
					soup_message_set_status_full (msg, SUNONE_ERROR_CALID_NOT_SPECIFIED,
								     "Calendar ID not specified");
				} else if (ival == 40) {
					soup_message_set_status_full (msg, SUNONE_ERROR_STORE_FAILED_DOUBLE_BOOKED,
								     "Resource has already been booked");
				} else if (ival == 43) {
					soup_message_set_status_full (msg, SUNONE_ERROR_ATTENDEE_GROUP_EXPANSION_CLIPPED,
								     "Attendee group expansion clipped");
				} else if (ival == 45) {
					soup_message_set_status_full (msg, SUNONE_ERROR_NOT_ALLOWED_TO_REQUEST_PUBLISH,
								     "You are not allowed to request publish");
				} else if (ival == 46) {
					soup_message_set_status_full (msg, SUNONE_ERROR_INSUFFICIENT_PARAMETERS,
								     "Insufficient parameters");
				} else if (ival == 47) {
					soup_message_set_status_full (msg, SUNONE_ERROR_MUSTBEOWNER_OPERATION,
								     "Owner privileges needed to perform this operation");
				} else if (ival == 58) {
					soup_message_set_status_full (msg, SUNONE_ERROR_WCAP_NO_SUCH_FORMAT,
								     "Supplied fmt-out is not a supported format");
				} else if (ival == 59) {
					soup_message_set_status_full (msg, SUNONE_ERROR_COMPONENT_NOT_FOUND,
								     "Event doesn't exist");
				} else if (ival == 60 || ival == 67 || ival == 77) {
					soup_message_set_status_full (msg, SUNONE_ERROR_BAD_ARGUMENTS,
								     "Bad arguments");
				} else if (ival == 69) {
					soup_message_set_status_full (msg, SUNONE_ERROR_LDAP_ERROR,
									"LDAP error");
				} else if (ival == 75) {
					soup_message_set_status_full (msg, SUNONE_ERROR_ANONYMOUS_NOT_ALLOWED,
									"Anonymous isn't allowed");
				} else if (ival == 78) {
					soup_message_set_status_full (msg, SUNONE_ERROR_READONLY_DATABASE,
									"Database is readonly");
				} else if (ival == 79) {
					soup_message_set_status_full (msg, SUNONE_ERROR_ATTENDEE_NOT_ALLOWED_TO_REQUEST_ON_MODIFY,
									"Attendee isn't allowed to request on modify");
				} else if (ival == 80) {
					soup_message_set_status_full (msg, SUNONE_ERROR_TRANSP_RESOURCE_NOT_ALLOWED,
									"Transparent resource isn't allowed");
				} else if (ival == 81) {
					soup_message_set_status_full (msg, SUNONE_ERROR_RECURRING_COMP_NOT_FOUND,
									"Can't find recurring component");
				}
				break;
			}
			
			icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
		}

		icalcomponent_free (icalcomp);
	}
}
