/*
**  URLName.m
**
**  Copyright (c) 2001, 2002
**
**  Author: Ludovic Marcotte <ludovic@Sophos.ca>
**
**  This library 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.1 of the License, or (at your option) any later version.
**  
**  This library 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 this library; if not, write to the Free Software
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <Pantomime/URLName.h>

#include <Pantomime/Constants.h>

#include <Foundation/NSDebug.h>
#include <Foundation/NSPathUtilities.h>

@implementation URLName

- (id) initWithString: (NSString *) theString
{
  return [self initWithString: theString
	       path: nil];
}

- (id) initWithString: (NSString *) theString
		 path: (NSString *) thePath
{
  self = [super init];

  // We initialize our ivars
  protocol = nil;
  foldername = nil;
  host = nil;
  port = 0;
  username = nil;
  password = nil;
 
  path = thePath;
  
  if ( path )
    {
      RETAIN(path);
    }

  // We now decode our URL
  [self _decodeURL: theString];
  
  return self;
}

- (void) dealloc
{
  TEST_RELEASE(protocol);
  TEST_RELEASE(foldername);
  TEST_RELEASE(path);
  TEST_RELEASE(host);
  TEST_RELEASE(username);
  TEST_RELEASE(password);
  
  [super dealloc];
}


//
// access/mutation methods
//
- (NSString *) protocol
{
  return protocol;
}

- (NSString *) foldername
{
  return foldername;
}

- (NSString *) path
{
  return path;
}

- (NSString *) host;
{
  return host;
}

- (int) port
{
  return port;
}

- (NSString *) username
{
  return username;
}

- (NSString *) password
{
  return password;
}

- (NSString *) description
{
  return [NSString stringWithFormat: @"protocol = (%@), foldername = (%@), path = (%@), host = (%@), port = (%d), username = (%@), password = (%@)",
		   [self protocol], [self foldername], [self path], [self host], [self port], [self username], [self password]];
}

- (NSString *) stringValue
{
  if ( [[self protocol] caseInsensitiveCompare: @"LOCAL"] == NSOrderedSame )
    {
      return [NSString stringWithFormat: @"local://%@/%@", [self path], [self foldername]];
    }
  else if  ( [[self protocol] caseInsensitiveCompare: @"IMAP"] == NSOrderedSame )
    {
      return [NSString stringWithFormat: @"imap://%@@%@/%@", [self username], [self host], [self foldername]];
    }
  else
    {
      return [NSString stringWithFormat: @"pop3://%@@%@", [self username], [self host]];
    }
}

@end


//
// Private methods
//
@implementation URLName (Private)

//// FIXME (finish!)
// imap://<iserver>/<foldername>
//
// Examples: imap://minbari.org/gray-council;UIDVALIDITY=385759045/;UID=20
//           imap://michael@minbari.org/users.*;type=list
//           imap://psicorp.org/~peter/%E6%97%A5%E6%9C%AC%E8%AA%9E/
//           imap://;AUTH=KERBEROS_V4@minbari.org/gray-council/;uid=20/;section=1.2
//           imap://;AUTH=*@minbari.org/gray%20council?SUBJECT%20shadows
//
// Note: The imap:// part isn't present in the received string as parameter.
//
- (void) _decodeIMAP: (NSString *) theString
{
  NSRange r1, r2;

  // We decode the username
  r1 = [theString rangeOfString: @"@"
		  options: NSBackwardsSearch];
  
  if ( r1.length )
    {
      username = [theString substringToIndex: r1.location];
      RETAIN(username);
    }
  else
    {
      r1.location = 0;
    }
  
  r2 = [theString rangeOfString: @"/"
		  options: 0
		  range: NSMakeRange(r1.location, [theString length] - r1.location)];
  
  if ( r1.length )
    {
      host = [theString substringWithRange: NSMakeRange(r1.location + 1, r2.location - r1.location - 1)];
    }
  else
    {
      host = [theString substringWithRange: NSMakeRange(r1.location, r2.location - r1.location)];
    }
  
  RETAIN(host);

  foldername = [theString substringFromIndex: (r2.location + 1)];
  RETAIN(foldername);

  //NSDebugLog(@"|%@| |%@| |%@|", username, host, foldername);
}


//
// local://<path>/<foldername> (full path)
//
// Note: The local:// part isn't present in the received string as parameter.
//
- (void) _decodeLocal: (NSString *) theString
{
  // If localMailDirectoryPath is nil, we return the last path component
  // of the URL as the foldername.
  if ( !path )
    {
      foldername = [theString lastPathComponent];
      RETAIN(foldername);
      
      path = [theString substringToIndex: ([theString length] - [foldername length])];
      RETAIN(path);
    }
  else
    {
      foldername = [theString substringFromIndex: ([path length] + 1)];
      RETAIN(foldername);
 
      //NSDebugLog(@"|%@| |%@|", path, foldername);
    }
}


//
// FIXME (finish!)
// pop://<user>;auth=<auth>@<host>:<port>
//
// Examples: pop://rg@mailsrv.qualcomm.com
//           pop://rg;AUTH=+APOP@mail.eudora.com:8110
//           pop://baz;AUTH=SCRAM-MD5@foo.bar
//
// Note: The pop:// part isn't present in the received string as parameter.
//
- (void) _decodePOP3: (NSString *) theString
{
  NSRange aRange;

  foldername = [[NSString alloc] initWithString: @"INBOX"];
  
  aRange = [theString rangeOfString: @"@"];
  
  username = [theString substringToIndex: aRange.location];
  RETAIN(username);

  host = [theString substringFromIndex: (aRange.location + 1)];
  RETAIN(host);
}


//
//
//
- (void) _decodeURL: (NSString *) theString
{
  NSRange aRange;

  // We first decode our protocol.
  aRange = [theString rangeOfString: @"://"];
  
  if ( aRange.length )
    {
      NSString *aString;

      protocol = [theString substringToIndex: aRange.location];
      RETAIN(protocol);
      
      aString = [theString substringFromIndex: (aRange.location + aRange.length)];

      if ( [protocol caseInsensitiveCompare: @"LOCAL"] == NSOrderedSame )
	{
	  [self _decodeLocal: aString];
	}
      else if ( [protocol caseInsensitiveCompare: @"POP3"] == NSOrderedSame )
	{
	  [self _decodePOP3: aString];
	}
      else if ( [protocol caseInsensitiveCompare: @"IMAP"] == NSOrderedSame )
	{
	  [self _decodeIMAP: aString];
	}
      else
	{
	  NSDebugLog(@"URLName: Malformed URL. Unsupported protocol specified.");
	}
    }
  else
    {
      NSDebugLog(@"URLName: Malformed URL.");
    }
}

@end
