/*
 *  Author:       Serg Stoyan
 *
 *  Classes:      AppDefaults : NSObject
 *
 *  Description:  Application defaults. Save/Load dictionaries from
 *                defaults file.
 */

#import <Foundation/NSDictionary.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSPathUtilities.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSValue.h>

#import "AppDefaults.h"

@implementation AppDefaults

- (id) init
{
  [super init];
  
  fileManager = [NSFileManager defaultManager];

  // Defaults
  defaultsDict = nil;
  sessionsDict = nil;
  defaultsFile = [[NSMutableString alloc] initWithString: NSHomeDirectory ()];
  [defaultsFile appendString: @"/GNUstep/Defaults/Connect"];

//  NSLog (@"init defaults file: %@", defaultsFile);

  if ([fileManager fileExistsAtPath: defaultsFile]
      == YES)
  {
    defaultsDict = [[NSMutableDictionary alloc]
      initWithContentsOfFile: defaultsFile];
  }

  if (defaultsDict == nil)
  {
    defaultsDict = RETAIN ([NSMutableDictionary dictionary]);
  }
  
  sessionsDict = [defaultsDict objectForKey: @"Sessions"];
  if (sessionsDict == nil)
  {
    [defaultsDict
      setObject: [NSMutableDictionary dictionary] forKey: @"Sessions"];
    sessionsDict = [defaultsDict objectForKey: @"Sessions"];
  }

  // Library

  return self;
}

- (void) dealloc
{
  NSLog (@"AppDefaults: dealloc");
 
  RELEASE (defaultsDict);

  [super dealloc];
}

- (void) writeToFile
{
  [defaultsDict writeToFile: defaultsFile atomically: YES];
}

/*-------------------------------------------------------------------------*
 *  Public methods 
 *-------------------------------------------------------------------------*/
- (NSMutableDictionary *) defaultsDict
{
  return defaultsDict;
}

- (NSMutableDictionary *) sessionsDict
{
  return sessionsDict;
}

- (NSArray *) sessionsList
{
  return [sessionsDict allKeys];
}

- (void) setDefaultSessionName: (NSString *)sessionName
{
  [defaultsDict setObject: sessionName forKey: @"DefaultSession"];
}

- (void) setRunOnStartupDefaultSession: (NSString *)run
{
  [defaultsDict setObject: run forKey: @"RunOnStartupDefaultSession"];
}

- (NSString *) defaultSessionName
{
  return [defaultsDict objectForKey: @"DefaultSession"];
}

- (NSString *) runOnStartupDefaultSession
{
  return [defaultsDict objectForKey: @"RunOnStartupDefaultSession"];
}

- (void) removeSessionWithName: (NSString *)name
{
  [sessionsDict removeObjectForKey: name];
  [self writeToFile];

  if ([self removeSessionBundle: name] == NO)
  {
    NSLog (@"session bundle remove error");
  }
}

- (NSDictionary *)defaultsForSession: (NSString *)sessionName
{
  return [sessionsDict objectForKey: sessionName];
}

/*-------------------------------------------------------------------------*
 *  Session bundles
 *-------------------------------------------------------------------------*/
// Returned NSString must be released later
- (NSString *) bundleDirForSessionWithName: (NSString *)name
{
  NSString        *libDir;
  NSMutableString *sessionDir;

  if ((libDir = [self appLibraryDirectory]) == nil)
  {
    return nil;
  }

  sessionDir = [[NSMutableString alloc] initWithString: libDir];
  [sessionDir appendString: @"/"];
  [sessionDir appendString: name];
  [sessionDir appendString: @".session/"];

  RELEASE (libDir);

  return sessionDir;
}

// Returned NSString must be released later
- (BOOL) createSessionBundle: (NSDictionary *)prefs
             withSessionName: (NSString *)name
{
  NSString *sessionDir = [self bundleDirForSessionWithName: name];

  if ([self fileExistsAtPath: sessionDir isCreate: YES isDirectory: YES])
  {
    RELEASE (sessionDir);
    return YES;
  }

  RELEASE (sessionDir);
  NSLog (@"!!! AppDefaults: session bundle creation error");

  return NO;
}

- (BOOL) removeSessionBundle: (NSString *)name
{
  NSString *sessionDir;

  sessionDir = [self bundleDirForSessionWithName: name];
  if ([fileManager removeFileAtPath: sessionDir handler: nil])
  {
    RELEASE (sessionDir);
    return YES;
  }
  
  RELEASE (sessionDir);
  
  return NO;
}

- (BOOL) writeString: (NSString *)string
            intoFile: (NSString *)file
    forSessionBundle: (NSString *)name
{
  NSMutableString *sessionFile;

  sessionFile = [[NSMutableString alloc] 
    initWithString: [self bundleDirForSessionWithName: name]];
  [sessionFile appendString: file];
  
  return [string writeToFile: sessionFile atomically: YES];
}

- (BOOL) clearFile: (NSString *)file
  forSessionBundle: (NSString *)name
{
  return NO;
}
  
- (BOOL) removeFile: (NSString *)file
   forSessionBundle: (NSString *)name
{
  return NO;
}

// Returned NSString must be released later
- (NSString *) sessionBundle: (NSString *)name
                fileContents: (NSString *)file
{
  NSString        *sessionDir = [self bundleDirForSessionWithName: name];
  NSMutableString *sessionFile;

  sessionFile = [[NSMutableString alloc] initWithString: sessionDir];
  [sessionFile appendString: file];

  RELEASE (sessionDir);

  return [[NSString alloc] initWithContentsOfFile: sessionFile];
}

/*-------------------------------------------------------------------------*
 *  Files and directories
 *-------------------------------------------------------------------------*/
// Returned NSString must be released later
- (NSString *) appLibraryDirectory
{
  NSMutableString  *libDir;

  libDir = [[NSMutableString alloc] initWithString: NSHomeDirectory ()];
  [libDir appendString: @"/GNUstep/.Connect"];

  if ([self fileExistsAtPath: libDir isCreate: YES isDirectory: YES] == NO)
  {
    NSLog (@"!!! AppDefaults: library dir determine error");
    return nil;
  }

  return libDir;
}

- (BOOL) fileExistsAtPath: (NSString *)file
                 isCreate: (BOOL)isCreate
              isDirectory: (BOOL)isDirectory
{
  BOOL isDir;

  // Create dirs and files with rwx --- --- premissions
  if ([fileManager fileExistsAtPath: file isDirectory: &isDir] == NO
      && isCreate == YES)
  {
    if (isDirectory == YES)
    {
      return [fileManager createDirectoryAtPath: file 
        attributes: [NSDictionary  
                     dictionaryWithObject: [NSNumber numberWithInt: 0700]
                     forKey: @"NSFilePosixPermissions"]];
    }
    else
    {
      return [fileManager createFileAtPath: file 
        contents: nil 
        attributes: [NSDictionary  
                     dictionaryWithObject: [NSNumber numberWithInt: 0700]
                     forKey: @"NSFilePosixPermissions"]];
    }
    return NO;
  }

  if (isDir == NO && isDirectory == YES)
  {
    NSLog (@"!!! AppDefaults: %@ file exists but not dir", file);
    return NO;
  }

  return YES;
}

@end

