/* 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,
				  	SoupMemoryUse req_use, 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, req_use, body, length);

	return msg;
}

#ifdef SUNONE_DEBUG
static void
print_header (const char *name, const char *value, gpointer data)
{
	printf ("%s: %s\n", name, 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_headers_foreach (msg->response_headers,
						print_header, NULL);
		if (msg->response_body->length &&
		    SUNONE_ERROR_IS_SUCCESSFUL (msg->status_code)) {
			if (jescs_long_debug) {
				printf ("\n%.*s\n", (int) msg->response_body->length,
					msg->response_body->data);
			} else {
			    	if (msg->response_body->length < RESPONSE_MAX_LENGTH)
					printf ("\n%.*s\n", (int) msg->response_body->length,
						msg->response_body->data);
			    	else 
			    		printf ("\n%.*s\n", RESPONSE_MAX_LENGTH,
						msg->response_body->data);
			}
		}
		printf ("\n");
	}
}
#endif

void
setup_message (SoupMessage *msg)
{
	soup_message_headers_append (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_headers_foreach (msg->request_headers,
						print_header, NULL);
		if (msg->request_body->length) {
			printf ("\n%.*s\n", (int)msg->request_body->length,
				msg->request_body->data);
		}
		printf ("\n");

		g_signal_connect (msg, "got-headers",
                  G_CALLBACK (sunone_debug_handler), NULL);
	}
#endif
}

void
parse_server_response (SoupMessage *msg, guint *status)
{
	icalcomponent *icalcomp;
	icalproperty *icalprop;

	if (!msg->response_body->data)
		return;

	icalcomp = sunone_util_icalparser_parse_string (msg->response_body->data, msg->response_body->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");
				} else if (ival == 82) {
					soup_message_set_status_full (msg,
								SUNONE_ERROR_BAD_MIME_TYPE,
								"The mime headers is malformatted");
				} else if (ival == 83) {
					soup_message_set_status_full (msg,
								SUNONE_ERROR_MISSING_BOUNDARY,
								"The mime boundary was not found");
				} else if (ival == 84) {
					soup_message_set_status_full (msg,
								SUNONE_ERROR_INVALID_ATTACHMENT,
								"The attachment is invalid");
				} else if (ival == 85) {
					soup_message_set_status_full (msg,
								SUNONE_ERROR_ATTACH_DELETE_SUCCESSFUL,
								"The attachments are delteed successfully");
				} else if (ival == 86) {
					soup_message_set_status_full (msg,
							SUNONE_ERROR_ATTACH_DELETE_PARTIAL,
							"Only a few attachments were deleted successfully");
				} else if (ival == 87) {
					soup_message_set_status_full (msg,
								SUNONE_ERROR_ATTACHMENT_NOT_FOUND,
								"Can't find attachment");
				}
				break;
			}
			
			icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
		}

		icalcomponent_free (icalcomp);
	}
}
