/*
 * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer. 
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#import <WebKit/WebNSFileManagerExtras.h>

#import <JavaScriptCore/Assertions.h>
#import <WebKit/WebKitNSStringExtras.h>
#import <WebKitSystemInterface.h>

#import <sys/mount.h>

@implementation NSFileManager (WebNSFileManagerExtras)

- (BOOL)_webkit_fileExistsAtPath:(NSString *)path isDirectory:(BOOL *)isDirectory traverseLink:(BOOL)flag
{
    BOOL result;
    NSDictionary *attributes;

    result = NO;
    if (isDirectory) {
        *isDirectory = NO;
    }

    attributes = [self fileAttributesAtPath:path traverseLink:flag];

    if (attributes) {
        result = YES;
        if ([[attributes objectForKey:NSFileType] isEqualToString:NSFileTypeDirectory]) {
            if (isDirectory) {
                *isDirectory = YES;
            }
        }
    }

    return result;
}

- (BOOL)_webkit_createIntermediateDirectoriesForPath:(NSString *)path attributes:(NSDictionary *)attributes
{
    BOOL result;
    NSArray *pathComponents;
    BOOL isDir;
    unsigned count;
    unsigned i;
    NSString *checkPath;
    NSMutableString *subpath;
            
    if (!path || [path length] == 0 || ![path isAbsolutePath]) {
        return NO;
    }

    result = NO;  

    // check to see if the path to the file already exists        
    if ([self _webkit_fileExistsAtPath:[path stringByDeletingLastPathComponent] isDirectory:&isDir traverseLink:YES]) {
        if (isDir) {
            result = YES;
        }
        else {
            result = NO;
        }
    }
    else {
        // create the path to the file
        result = YES;  

        // assume that most of the path exists, look backwards until we find an existing subpath
        checkPath = path;
        while (![checkPath isEqualToString:@"/"]) {
            checkPath = [checkPath stringByDeletingLastPathComponent];
            if ([self _webkit_fileExistsAtPath:checkPath isDirectory:&isDir traverseLink:YES]) {
                if (isDir) {
                    break;
                }
                else {
                    // found a leaf node, can't continue
                    result = NO;
                    break;
                }
            }
        }

        if (result) {
            // now build up the path to the point where we found existing paths
            subpath = [[NSMutableString alloc] initWithCapacity:[path length]];
            pathComponents = [path componentsSeparatedByString:@"/"];    
            count = [pathComponents count];
            i = 0;
            while (i < count - 1 && ![subpath isEqualToString:checkPath]) {
                if (i > 0) {
                    [subpath appendString:@"/"];
                }
                [subpath appendString:[pathComponents objectAtIndex:i]];  
                i++;  
            }
            
            // now create the parts of the path that did not yet exist
            while (i < count - 1) {
                if ([(NSString *)[pathComponents objectAtIndex:i] length] == 0) {
                    continue;
                }
                if (i > 0) {
                    [subpath appendString:@"/"];
                }
                [subpath appendString:[pathComponents objectAtIndex:i]];
                
                // does this directory exist?
                if ([self _webkit_fileExistsAtPath:subpath isDirectory:&isDir traverseLink:YES]) {
                    if (!isDir) {
                        // ran into a leaf node of some sort
                        result = NO;
                        break;
                    }
                }
                else {
                    // subpath does not exist - create it
                    if (![self createDirectoryAtPath:subpath attributes:attributes]) {
                        // failed to create subpath
                        result = NO;
                        break;
                    }
                }
                i++; 
            }
            
            [subpath release];
        }
        
    }    
                            
    return result;
}

- (BOOL)_webkit_createDirectoryAtPathWithIntermediateDirectories:(NSString *)path attributes:(NSDictionary *)attributes
{
    // Be really optimistic - assume that in the common case, the directory exists.
    BOOL isDirectory;
    if ([self fileExistsAtPath:path isDirectory:&isDirectory] && isDirectory) {
        return YES;
    }

    // Assume the next most common case is that the parent directory already exists
    if ([self createDirectoryAtPath:path attributes:attributes]) {
        return YES;
    }

    // Do it the hard way 
    return [self _webkit_createIntermediateDirectoriesForPath:path attributes:attributes] && [self createDirectoryAtPath:path attributes:attributes];
}

- (BOOL)_webkit_createFileAtPathWithIntermediateDirectories:(NSString *)path contents:(NSData *)contents attributes:(NSDictionary *)attributes directoryAttributes:(NSDictionary *)directoryAttributes
{
    // Be optimistic - try just creating the file first, assuming intermediate directories exist. 
    if ([self createFileAtPath:path contents:contents attributes:attributes]) {
        return YES;
    }

    return ([self _webkit_createIntermediateDirectoriesForPath:path attributes:directoryAttributes] && [self createFileAtPath:path contents:contents attributes:attributes]);
}

- (BOOL)_webkit_removeFileOnlyAtPath:(NSString *)path
{
    struct statfs buf;
    BOOL result = unlink([path fileSystemRepresentation]) == 0;

    // For mysterious reasons, MNT_DOVOLFS is the flag for "supports resource fork"
    if ((statfs([path fileSystemRepresentation], &buf) == 0) && !(buf.f_flags & MNT_DOVOLFS)) {
        NSString *lastPathComponent = [path lastPathComponent];
        if ([lastPathComponent length] != 0 && ![lastPathComponent isEqualToString:@"/"]) {
            NSString *resourcePath = [[path stringByDeletingLastPathComponent] stringByAppendingString:[@"._" stringByAppendingString:lastPathComponent]];
            if (unlink([resourcePath fileSystemRepresentation]) != 0) {
                result = NO;
            }
        }
    }

    return result;
}

- (void)_webkit_backgroundRemoveFileAtPath:(NSString *)path
{
    NSFileManager *manager;
    NSString *moveToSubpath;
    NSString *moveToPath;
    int i;
    
    manager = [NSFileManager defaultManager];
    
    i = 0;
    moveToSubpath = [path stringByDeletingLastPathComponent];
    do {
        moveToPath = [NSString stringWithFormat:@"%@/.tmp%d", moveToSubpath, i];
        i++;
    } while ([manager fileExistsAtPath:moveToPath]);

    if ([manager movePath:path toPath:moveToPath handler:nil]) {
        [NSThread detachNewThreadSelector:@selector(_performRemoveFileAtPath:) toTarget:self withObject:moveToPath];
    }

}

- (void)_webkit_backgroundRemoveLeftoverFiles:(NSString *)path
{
    NSFileManager *manager;
    NSString *leftoverSubpath;
    NSString *leftoverPath;
    int i;
    
    manager = [NSFileManager defaultManager];
    leftoverSubpath = [path stringByDeletingLastPathComponent];
    
    i = 0;
    while (1) {
        leftoverPath = [NSString stringWithFormat:@"%@/.tmp%d", leftoverSubpath, i];
        if (![manager fileExistsAtPath:leftoverPath]) {
            break;
        }
        [NSThread detachNewThreadSelector:@selector(_performRemoveFileAtPath:) toTarget:self withObject:leftoverPath];
        i++;
    }
}

- (NSString *)_webkit_carbonPathForPath:(NSString *)posixPath
{
    OSStatus error;
    FSRef ref, rootRef, parentRef;
    FSCatalogInfo info;
    NSMutableArray *carbonPathPieces;
    HFSUniStr255 nameString;

    // Make an FSRef.
    error = FSPathMakeRef((const UInt8 *)[posixPath fileSystemRepresentation], &ref, NULL);
    if (error != noErr) {
        return nil;
    }

    // Get volume refNum.
    error = FSGetCatalogInfo(&ref, kFSCatInfoVolume, &info, NULL, NULL, NULL);
    if (error != noErr) {
        return nil;
    }

    // Get root directory FSRef.
    error = FSGetVolumeInfo(info.volume, 0, NULL, kFSVolInfoNone, NULL, NULL, &rootRef);
    if (error != noErr) {
        return nil;
    }

    // Get the pieces of the path.
    carbonPathPieces = [NSMutableArray array];
    for (;;) {
        error = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, &nameString, NULL, &parentRef);
        if (error != noErr) {
            return nil;
        }
        [carbonPathPieces insertObject:[NSString stringWithCharacters:nameString.unicode length:nameString.length] atIndex:0];
        if (FSCompareFSRefs(&ref, &rootRef) == noErr) {
            break;
        }
        ref = parentRef;
    }

    // Volume names need trailing : character.
    if ([carbonPathPieces count] == 1) {
        [carbonPathPieces addObject:@""];
    }

    return [carbonPathPieces componentsJoinedByString:@":"];
}

- (void)_webkit_setMetadataURL:(NSString *)URLString referrer:(NSString *)referrer atPath:(NSString *)path
{
    ASSERT(URLString);
    ASSERT(path);
    WKSetMetadataURL(URLString, referrer, path);
}

- (NSString *)_webkit_startupVolumeName
{
    NSString *path = [self _webkit_carbonPathForPath:@"/"];
    return [path substringToIndex:[path length]-1];
}

- (NSString *)_webkit_pathWithUniqueFilenameForPath:(NSString *)path
{
    // "Fix" the filename of the path.
    NSString *filename = [[path lastPathComponent] _webkit_filenameByFixingIllegalCharacters];
    path = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:filename];

    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:path]) {
        // Don't overwrite existing file by appending "-n", "-n.ext" or "-n.ext.ext" to the filename.
        NSString *extensions = nil;
        NSString *pathWithoutExtensions;
        NSString *lastPathComponent = [path lastPathComponent];
        NSRange periodRange = [lastPathComponent rangeOfString:@"."];
        
        if (periodRange.location == NSNotFound) {
            pathWithoutExtensions = path;
        } else {
            extensions = [lastPathComponent substringFromIndex:periodRange.location + 1];
            lastPathComponent = [lastPathComponent substringToIndex:periodRange.location];
            pathWithoutExtensions = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:lastPathComponent];
        }

        NSString *pathWithAppendedNumber;
        unsigned i;

        for (i = 1; 1; i++) {
            pathWithAppendedNumber = [NSString stringWithFormat:@"%@-%d", pathWithoutExtensions, i];
            path = [extensions length] ? [pathWithAppendedNumber stringByAppendingPathExtension:extensions] : pathWithAppendedNumber;
            if (![fileManager fileExistsAtPath:path]) {
                break;
            }
        }
    }

    return path;
}

@end
