/*
  Copyright (C) 2000-2005 SKYRIX Software AG

  This file is part of SOPE.

  SOPE is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the
  Free Software Foundation; either version 2, or (at your option) any
  later version.

  SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with SOPE; see the file COPYING.  If not, write to the
  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  02111-1307, USA.
*/

#include "iCalPublishAction.h"
#include "iCalPortalUser.h"
#include <NGObjWeb/WEClientCapabilities.h>
#include <NGMime/NGMime.h>
#include "common.h"

/*
  Publish Sequence in Outlook 2000 is:
  a) post an empty request without creds => 401
  b) post an empty request with creds => 200
  c) post the full request with (validated) creds
*/

@implementation iCalPublishAction

- (void)dealloc {
  [super dealloc];
}

- (int)maxCalSizeForUser:(iCalPortalUser *)_user {
  return 200 * 1024; /* 200K for now */
}

- (WOResponse *)run {
  WORequest      *rq;
  iCalPortalUser *user;
  WOResponse  *r;
  NSData      *data;
  NSException *e;
  int okStatus = 201 /* created */;
  
  if ((user = [self user]) == nil) {
    return nil;
  }

  rq = [self request];
  
  r = [WOResponse responseWithRequest:[self request]];
  
  /* check for OL 2000 (which does a "POST" to publish requests) */
  
  if ([[rq method] isEqualToString:@"POST"]) {
    /* could extract file name from content-disposition ... */
    NGMimeMultipartBody *body;
    BOOL isEmpty = NO;
    
    okStatus = 200; /* override for OL 2K */
    
    [self debugWithFormat:@"got a post from: %@",
	    [rq headerForKey:@"user-agent"]];
    
    if ((body = [[rq httpRequest] body]) == nil)
      isEmpty = YES;
    else if (![body isKindOfClass:[NGMimeMultipartBody class]])
      /* probably a bit strict ... */
      isEmpty = YES;
    else {
      NSArray *parts;

      if ((parts = [body parts]) == nil)
	isEmpty = YES;
      else if ([parts count] == 0)
	isEmpty = YES;
      else {
	NGMimeBodyPart *part;
	
	part = [parts objectAtIndex:0];
	data = [part body];
      }
    }
    
    if (isEmpty) {
      [self debugWithFormat:@"but the content was empty, returning 200 !!!"];
      [r setStatus:200];
      return r;
    }
  }
  else
    data = [[self request] content];
  
  /* process a "usual" PUT */
  
  [self debugWithFormat:@"write calendar of user: %@", user];
  [self debugWithFormat:@"  url of: %@", [self requestUser]];
  [self debugWithFormat:@"  cal:    %@", [self requestCalendarPath]];
  
  if (data == nil) data = [[[NSData alloc] init] autorelease];
  
  if ([data length] > [self maxCalSizeForUser:user]) {
    [self logWithFormat:@"calendar to be published exceeds maximum size !"];
    [r setStatus:500];
  }
  else if ((e = [user writeICalendarData:data
		      toCalendar:[self requestCalendarPath]])) {
    /* failed */
    [self logWithFormat:@"calendar upload failed: %@", e];
    
    [r setStatus:500 /* server error */];
    [r appendContentString:@"<h3>calendar upload failed !</h3>"];
    [r appendContentHTMLString:[e description]];
  }
  else {
    WEClientCapabilities *cc;
    
    cc = [[self request] clientCapabilities];
    
    if ([cc isWebFolder]) {
      [r setStatus:200 /* OK */];
    }
    else {
      /* 201 is generated by mod_dav, when iCal.app does a PUT */
      [r setStatus:okStatus];
      [r appendContentString:@"the calendar has been created ..."];
    }
  }
  
  return r;
}

@end /* iCalPublishAction */
