//
// main.c
// mulle-plist-from-files
//
// Created by Nat! on 07.02.13.
// Copyright (c) 2013 Mulle kybernetiK. All rights reserved.
//
// http://github.com/mulle-nat/mulle-plist-from-files
// http://www.mulle-kybernetik.com
// http://www.mulle-kybernetik.com/weblog
//
#import <Foundation/Foundation.h>


static char  version[] = "1.0";


static id   get_value_from_file_or_dir( NSFileManager *fileManager, NSString *name, NSString *dir);


static id   get_value_from_dir( NSFileManager *fileManager, NSString *dir)
{
   NSEnumerator          *rover;
   NSMutableDictionary   *dictionary;
   NSString              *name;
   id                    value;
   
   dictionary = [NSMutableDictionary dictionary];
   rover = [fileManager enumeratorAtPath:dir];
   while( name = [rover nextObject])
   {
      value = get_value_from_file_or_dir( fileManager, name, dir);
      if( ! value)
         return( nil);
      
      [dictionary setObject:value
                     forKey:name];
   }
   return( dictionary);
}


static id   get_value_from_file_or_dir( NSFileManager *fileManager, NSString *name, NSString *dir)
{
   BOOL                  isDir;
   NSData                *data;
   NSError               *error;
   NSPropertyListFormat  format;
   NSString              *path;
   id                    plist;
   
   path = name;
   if( ! [path isAbsolutePath])
      path = [dir stringByAppendingPathComponent:name];

   data = [NSData dataWithContentsOfFile:path
                                 options:NSDataReadingMappedIfSafe
                                   error:&error];
   if( ! data)
   {
      if( ! [fileManager fileExistsAtPath:path
                              isDirectory:&isDir])
      {
         NSLog( @"File %@ not found", path);
         return( nil);
      }
      if( ! isDir)
      {
         NSLog( @"File %@ open failed %@", path, error);
         return( nil);
      }
      // do the recursive
      return( get_value_from_dir( fileManager, path));
   }

   plist = [NSPropertyListSerialization propertyListWithData:data
                                                     options:NSPropertyListImmutable
                                                      format:&format
                                                       error:&error];
   return( plist ? plist : data);
}


static void   write_plist( id plist,FILE *stream)
{
   NSData   *data;
   
   data = [[plist description] dataUsingEncoding:NSUTF8StringEncoding];
   fwrite( [data bytes], [data length], 1, stream);
}


   
int main(int argc, const char * argv[])
{
   NSAutoreleasePool     *pool;
   NSArray               *arguments;
   NSEnumerator          *rover;
   NSFileManager         *fileManager;
   NSMutableDictionary   *dictionary;
   NSProcessInfo         *processInfo;
   NSString              *cdir;
   NSString              *key;
   NSString              *name;
   NSString              *processName;
   id                    value;
   
   pool = [NSAutoreleasePool new];
   
   processInfo = [NSProcessInfo processInfo];
   arguments   = [processInfo arguments];
   rover       = [arguments objectEnumerator];
   name        = [rover nextObject];
   processName = [name lastPathComponent];
   if( [arguments count] == 1)
      goto usage;
   
   dictionary  = [NSMutableDictionary dictionary];
   fileManager = [NSFileManager defaultManager];

   cdir = [fileManager currentDirectoryPath];
   
   while( name = [rover nextObject])
   {
      value = get_value_from_file_or_dir( fileManager, name, cdir);
      if( ! value)
         return( -1);

      key = [name lastPathComponent];
      [dictionary setObject:value
                     forKey:key];
   }
   
   write_plist( dictionary, stdout);

   return( 0);
   
usage:
   fprintf( stderr, "%s <file> [filename ...]\n", [processName cString]);
   fprintf( stderr, "\tv%s\n", version);
   return( -1);
}