//  This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files.
//  Copyright (C) 1997-1998, 2000-2001, 2004-2006  Steve Nygard

#import "CDClassDump.h"

#import <Foundation/Foundation.h>
#import "NSArray-Extensions.h"
#import "CDDylibCommand.h"
#import "CDFatArch.h"
#import "CDFatFile.h"
#import "CDMachOFile.h"
#import "CDObjCSegmentProcessor.h"
#import "CDStructureTable.h"
#import "CDSymbolReferences.h"
#import "CDType.h"
#import "CDTypeFormatter.h"
#import "CDTypeParser.h"

@implementation CDClassDump

static NSMutableSet *wrapperExtensions = nil;

+ (void)initialize;
{
    // TODO (old): Try grabbing these from an environment variable.
    wrapperExtensions = [[NSMutableSet alloc] init];
    [wrapperExtensions addObject:@"app"];
    [wrapperExtensions addObject:@"framework"];
    [wrapperExtensions addObject:@"bundle"];
    [wrapperExtensions addObject:@"palette"];
    [wrapperExtensions addObject:@"plugin"];
}

// How does this handle something ending in "/"?

+ (BOOL)isWrapperAtPath:(NSString *)path;
{
    return [wrapperExtensions containsObject:[path pathExtension]];
}

+ (NSString *)pathToMainFileOfWrapper:(NSString *)wrapperPath;
{
    NSString *base, *extension, *mainFile;

    base = [wrapperPath lastPathComponent];
    extension = [base pathExtension];
    base = [base stringByDeletingPathExtension];

    if ([@"framework" isEqual:extension] == YES) {
        mainFile = [NSString stringWithFormat:@"%@/%@", wrapperPath, base];
    } else {
        // app, bundle, palette, plugin
        mainFile = [NSString stringWithFormat:@"%@/Contents/MacOS/%@", wrapperPath, base];
    }

    return mainFile;
}

// Allow user to specify wrapper instead of the actual Mach-O file.
+ (NSString *)adjustUserSuppliedPath:(NSString *)path;
{
    NSString *fullyResolvedPath, *basePath, *resolvedBasePath;

    if ([self isWrapperAtPath:path] == YES) {
        path = [self pathToMainFileOfWrapper:path];
    }

    fullyResolvedPath = [path stringByResolvingSymlinksInPath];
    basePath = [path stringByDeletingLastPathComponent];
    resolvedBasePath = [basePath stringByResolvingSymlinksInPath];
    //NSLog(@"fullyResolvedPath: %@", fullyResolvedPath);
    //NSLog(@"basePath:          %@", basePath);
    //NSLog(@"resolvedBasePath:  %@", resolvedBasePath);

    // I don't want to resolve all of the symlinks, just the ones starting from the wrapper.
    // If I have a symlink from my home directory to /System/Library/Frameworks/AppKit.framework, I want to see the
    // path to my home directory.
    // This is an easy way to cheat so that we don't have to deal with NSFileManager ourselves.

    // This is clever, but it fails when the symlink goes outside of the wrapper.  For example, currently
    // /System/Library/PrivateFrameworks/ICACameraPriv.framework/ICACameraPriv is a symbolic link to
    // ../../Frameworks/ICADevices.framework/Versions/A/ICADevices and so now we check to make sure the
    // first parts of the paths are the same.
    if ([fullyResolvedPath hasPrefix:resolvedBasePath] == NO)
        return fullyResolvedPath;

    return [basePath stringByAppendingString:[fullyResolvedPath substringFromIndex:[resolvedBasePath length]]];
}

- (id)init;
{
    if ([super init] == nil)
        return nil;

    executablePath = nil;

    machOFilesByID = [[NSMutableDictionary alloc] init];
    objCSegmentProcessors = [[NSMutableArray alloc] init];

    structureTable = [[CDStructureTable alloc] init];
    [structureTable setAnonymousBaseName:@"CDAnonymousStruct"];
    [structureTable setName:@"Structs"];

    unionTable = [[CDStructureTable alloc] init];
    [unionTable setAnonymousBaseName:@"CDAnonymousUnion"];
    [unionTable setName:@"Unions"];

    ivarTypeFormatter = [[CDTypeFormatter alloc] init];
    [ivarTypeFormatter setShouldExpand:NO];
    [ivarTypeFormatter setShouldAutoExpand:YES];
    [ivarTypeFormatter setBaseLevel:1];
    [ivarTypeFormatter setDelegate:self];

    methodTypeFormatter = [[CDTypeFormatter alloc] init];
    [methodTypeFormatter setShouldExpand:NO];
    [methodTypeFormatter setShouldAutoExpand:NO];
    [methodTypeFormatter setBaseLevel:0];
    [methodTypeFormatter setDelegate:self];

    structDeclarationTypeFormatter = [[CDTypeFormatter alloc] init];
    [structDeclarationTypeFormatter setShouldExpand:YES]; // But don't expand named struct members...
    [structDeclarationTypeFormatter setShouldAutoExpand:YES];
    [structDeclarationTypeFormatter setBaseLevel:0];
    [structDeclarationTypeFormatter setDelegate:self]; // But need to ignore some things?

    frameworkNamesByClassName = [[NSMutableDictionary alloc] init];
    preferredCPUType = CPU_TYPE_ANY;
    //preferredCPUType = CPU_TYPE_POWERPC;
    //preferredCPUType = CPU_TYPE_I386;

    flags.shouldShowHeader = YES;

    return self;
}

- (void)dealloc;
{
    [executablePath release];
    [outputPath release];

    [machOFilesByID release];
    [objCSegmentProcessors release];

    [structureTable release];
    [unionTable release];

    [ivarTypeFormatter release];
    [methodTypeFormatter release];
    [structDeclarationTypeFormatter release];

    [frameworkNamesByClassName release];

    if (flags.shouldMatchRegex == YES)
        regfree(&compiledRegex);

    [super dealloc];
}

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

- (void)setExecutablePath:(NSString *)newPath;
{
    if (newPath == executablePath)
        return;

    [executablePath release];
    executablePath = [newPath retain];
}

- (BOOL)shouldProcessRecursively;
{
    return flags.shouldProcessRecursively;
}

- (void)setShouldProcessRecursively:(BOOL)newFlag;
{
    flags.shouldProcessRecursively = newFlag;
}

- (BOOL)shouldGenerateSeparateHeaders;
{
    return flags.shouldGenerateSeparateHeaders;
}

- (void)setShouldGenerateSeparateHeaders:(BOOL)newFlag;
{
    flags.shouldGenerateSeparateHeaders = newFlag;
}

- (BOOL)shouldSortClasses;
{
    return flags.shouldSortClasses;
}

- (void)setShouldSortClasses:(BOOL)newFlag;
{
    flags.shouldSortClasses = newFlag;
}

- (BOOL)shouldSortClassesByInheritance;
{
    return flags.shouldSortClassesByInheritance;
}

- (void)setShouldSortClassesByInheritance:(BOOL)newFlag;
{
    flags.shouldSortClassesByInheritance = newFlag;
}

- (BOOL)shouldSortMethods;
{
    return flags.shouldSortMethods;
}

- (void)setShouldSortMethods:(BOOL)newFlag;
{
    flags.shouldSortMethods = newFlag;
}

- (BOOL)shouldShowIvarOffsets;
{
    return flags.shouldShowIvarOffsets;
}

- (void)setShouldShowIvarOffsets:(BOOL)newFlag;
{
    flags.shouldShowIvarOffsets = newFlag;
}

- (BOOL)shouldShowMethodAddresses;
{
    return flags.shouldShowMethodAddresses;
}

- (void)setShouldShowMethodAddresses:(BOOL)newFlag;
{
    flags.shouldShowMethodAddresses = newFlag;
}

- (BOOL)shouldMatchRegex;
{
    return flags.shouldMatchRegex;
}

- (void)setShouldMatchRegex:(BOOL)newFlag;
{
    if (flags.shouldMatchRegex == YES && newFlag == NO)
        regfree(&compiledRegex);

    flags.shouldMatchRegex = newFlag;
}

- (BOOL)shouldShowHeader;
{
    return flags.shouldShowHeader;
}

- (void)setShouldShowHeader:(BOOL)newFlag;
{
    flags.shouldShowHeader = newFlag;
}

- (BOOL)setRegex:(char *)regexCString errorMessage:(NSString **)errorMessagePointer;
{
    int result;

    if (flags.shouldMatchRegex == YES)
        regfree(&compiledRegex);

    result = regcomp(&compiledRegex, regexCString, REG_EXTENDED);
    if (result != 0) {
        char regex_error_buffer[256];

        if (regerror(result, &compiledRegex, regex_error_buffer, 256) > 0) {
            if (errorMessagePointer != NULL) {
                *errorMessagePointer = [NSString stringWithCString:regex_error_buffer];
            }
        } else {
            if (errorMessagePointer != NULL)
                *errorMessagePointer = nil;
        }

        return NO;
    }

    [self setShouldMatchRegex:YES];

    return YES;
}

- (BOOL)regexMatchesString:(NSString *)aString;
{
    int result;

    result = regexec(&compiledRegex, [aString UTF8String], 0, NULL, 0);
    if (result != 0) {
        if (result != REG_NOMATCH) {
            char regex_error_buffer[256];

            if (regerror(result, &compiledRegex, regex_error_buffer, 256) > 0)
                NSLog(@"Error with regex matching string, %@", [NSString stringWithCString:regex_error_buffer]);
        }

        return NO;
    }

    return YES;
}

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

- (void)setOutputPath:(NSString *)aPath;
{
    if (aPath == outputPath)
        return;

    [outputPath release];
    outputPath = [aPath retain];
}

- (cpu_type_t)preferredCPUType;
{
    return preferredCPUType;
}

- (void)setPreferredCPUType:(cpu_type_t)aPreferredCPUType;
{
    preferredCPUType = aPreferredCPUType;
}

- (BOOL)containsObjectiveCSegments;
{
    unsigned int count, index;

    count = [objCSegmentProcessors count];
    for (index = 0; index < count; index++) {
        if ([[objCSegmentProcessors objectAtIndex:index] hasModules])
            return YES;
    }

    return NO;
}

- (CDStructureTable *)structureTable;
{
    return structureTable;
}

- (CDStructureTable *)unionTable;
{
    return unionTable;
}

- (CDTypeFormatter *)ivarTypeFormatter;
{
    return ivarTypeFormatter;
}

- (CDTypeFormatter *)methodTypeFormatter;
{
    return methodTypeFormatter;
}

- (CDTypeFormatter *)structDeclarationTypeFormatter;
{
    return structDeclarationTypeFormatter;
}

// Return YES if successful, NO if there was an error.
- (BOOL)processFilename:(NSString *)aFilename;
{
    NSString *adjustedPath;

    adjustedPath = [[self class] adjustUserSuppliedPath:aFilename];
    [self setExecutablePath:[adjustedPath stringByDeletingLastPathComponent]];

    return [self _processFilename:adjustedPath];
}

// Return YES if successful, NO if there was an error.
- (BOOL)_processFilename:(NSString *)aFilename;
{
    CDFatFile *aFatFile;
    CDMachOFile *aMachOFile;
    CDObjCSegmentProcessor *aProcessor;

    // TODO (2005-07-08): This isn't good enough.  You only have your
    // choice on the main file.  Link frameworks MUST be the same
    // architecture, either as a stand-alone Mach-O file or within a fat file.

    // Initial combinations:
    // 1. macho file, no cpu preference
    // 2. macho file, cpu preference same as macho file
    // 3. macho file, cpu preference different from macho file
    // 4. fat file, no cpu preference
    // 5. fat file, cpu preference contained in fat file
    // 6. fat file, cpu preference not contained in fat file
    //
    // Actions:
    // 1, 2, 4, 5: All subsequent files must be same cpu
    // 3. Print message saying that arch isn't available in this macho file
    // 6. Print message saying that arch isn't available in this fat file
    //
    // For linked frameworks/libraries, if the arch isn't available silently skip?

    aFatFile = [[CDFatFile alloc] initWithFilename:aFilename];
    if (aFatFile == nil) {
        aMachOFile = [[CDMachOFile alloc] initWithFilename:aFilename];
        if (aMachOFile == nil) {
            fprintf(stderr, "class-dump: Input file (%s) is neither a Mach-O file nor a fat archive.\n", [aFilename fileSystemRepresentation]);
            return NO;
        }

        if (preferredCPUType == CPU_TYPE_ANY) {
            preferredCPUType = [aMachOFile cpuType];
        } else if ([aMachOFile cpuType] != preferredCPUType) {
            fprintf(stderr, "class-dump: Mach-O file (%s) does not contain required cpu type: %s.\n",
                    [aFilename fileSystemRepresentation], [CDNameForCPUType(preferredCPUType) UTF8String]);
            [aMachOFile release];
            return NO;
        }
    } else {
        CDFatArch *fatArch;

        fatArch = [aFatFile fatArchWithCPUType:preferredCPUType];
        if (fatArch == nil) {
            if (preferredCPUType == CPU_TYPE_ANY)
                fprintf(stderr, "class-dump: Fat archive (%s) did not contain any cpu types!\n", [aFilename fileSystemRepresentation]);
            else
                fprintf(stderr, "class-dump: Fat archive (%s) does not contain required cpu type: %s.\n",
                        [aFilename fileSystemRepresentation], [CDNameForCPUType(preferredCPUType) UTF8String]);
            [aFatFile release];
            return NO;
        }

        if (preferredCPUType == CPU_TYPE_ANY) {
            preferredCPUType = [fatArch cpuType];
        }

        aMachOFile = [[CDMachOFile alloc] initWithFilename:aFilename archiveOffset:[fatArch offset]];
        [aFatFile release];

        if (aMachOFile == nil)
            return NO;
    }

    [aMachOFile setDelegate:self];

    // TODO (2005-07-03): Look for the newer exception handling stuff.
    NS_DURING {
        [aMachOFile process];
    } NS_HANDLER {
        [aMachOFile release];
        return NO;
    } NS_ENDHANDLER;

    aProcessor = [[CDObjCSegmentProcessor alloc] initWithMachOFile:aMachOFile];
    [aProcessor process];
    [objCSegmentProcessors addObject:aProcessor];
    [aProcessor release];

    assert([aMachOFile filename] != nil);
    [machOFilesByID setObject:aMachOFile forKey:[aMachOFile filename]];

    [aMachOFile release];

    return YES;
}

- (void)generateOutput;
{
    [self registerPhase:1];
    [self registerPhase:2];
    [self generateMemberNames];

    if ([self shouldGenerateSeparateHeaders] == YES)
        [self generateSeparateHeaders];
    else
        [self generateToStandardOut];
}

- (void)generateToStandardOut;
{
    NSMutableString *resultString;
    int count, index;
    NSData *data;

    resultString = [[NSMutableString alloc] init];

    [self appendHeaderToString:resultString];

    if ([self containsObjectiveCSegments]) {
        [self appendStructuresToString:resultString symbolReferences:nil];

        count = [objCSegmentProcessors count];
        for (index = 0; index < count; index++) {
            [[objCSegmentProcessors objectAtIndex:index] appendFormattedString:resultString classDump:self];
        }
    } else {
        [resultString appendString:@"This file does not contain any Objective-C runtime information.\n"];
    }

    data = [resultString dataUsingEncoding:NSUTF8StringEncoding];
    [(NSFileHandle *)[NSFileHandle fileHandleWithStandardOutput] writeData:data];

    [resultString release];
}

- (void)generateSeparateHeaders;
{
    int count, index;

    if ([self containsObjectiveCSegments] == NO) {
        NSLog(@"Warning: This file does not contain any Objective-C runtime information.");
        return;
    }

    [self buildClassFrameworks];

    if (outputPath != nil) {
        NSFileManager *fileManager;
        BOOL isDirectory;

        fileManager = [NSFileManager defaultManager];
        if ([fileManager fileExistsAtPath:outputPath isDirectory:&isDirectory] == NO) {
            BOOL result;

            result = [fileManager createDirectoryAtPath:outputPath attributes:nil];
            if (result == NO) {
                NSLog(@"Error: Couldn't create output directory: %@", outputPath);
                return;
            }
        } else if (isDirectory == NO) {
            NSLog(@"Error: File exists at output path: %@", outputPath);
            return;
        }
    }

    [self generateStructureHeader];

    count = [objCSegmentProcessors count];
    for (index = 0; index < count; index++) {
        [[objCSegmentProcessors objectAtIndex:index] generateSeparateHeadersClassDump:self];
    }
}

- (void)generateStructureHeader;
{
    NSMutableString *resultString;
    NSString *filename;
    CDSymbolReferences *symbolReferences;
    NSString *referenceString;
    unsigned int referenceIndex;

    resultString = [[NSMutableString alloc] init];
    [self appendHeaderToString:resultString];

    symbolReferences = [[CDSymbolReferences alloc] init];
    referenceIndex = [resultString length];

    [self appendStructuresToString:resultString symbolReferences:symbolReferences];

    referenceString = [symbolReferences referenceString];
    if (referenceString != nil)
        [resultString insertString:referenceString atIndex:referenceIndex];

    filename = @"CDStructures.h";
    if (outputPath != nil)
        filename = [outputPath stringByAppendingPathComponent:filename];

    [[resultString dataUsingEncoding:NSUTF8StringEncoding] writeToFile:filename atomically:YES];

    [symbolReferences release];
    [resultString release];
}

- (void)logInfo;
{
    [structureTable logInfo];
    [unionTable logInfo];
}

- (void)appendStructuresToString:(NSMutableString *)resultString symbolReferences:(CDSymbolReferences *)symbolReferences;
{
    [structureTable appendNamedStructuresToString:resultString classDump:self formatter:structDeclarationTypeFormatter symbolReferences:symbolReferences];
    [structureTable appendTypedefsToString:resultString classDump:self formatter:structDeclarationTypeFormatter symbolReferences:symbolReferences];

    [unionTable appendNamedStructuresToString:resultString classDump:self formatter:structDeclarationTypeFormatter symbolReferences:symbolReferences];
    [unionTable appendTypedefsToString:resultString classDump:self formatter:structDeclarationTypeFormatter symbolReferences:symbolReferences];
}

- (CDMachOFile *)machOFileWithID:(NSString *)anID;
{
    NSString *adjustedID;
    CDMachOFile *aMachOFile;
    NSString *replacementString = @"@executable_path";

    if ([anID hasPrefix:replacementString] == YES) {
        adjustedID = [executablePath stringByAppendingString:[anID substringFromIndex:[replacementString length]]];
    } else {
        adjustedID = anID;
    }

    aMachOFile = [machOFilesByID objectForKey:adjustedID];
    if (aMachOFile == nil) {
        [self _processFilename:adjustedID];
        aMachOFile = [machOFilesByID objectForKey:adjustedID];
    }

    return aMachOFile;
}

- (void)machOFile:(CDMachOFile *)aMachOFile loadDylib:(CDDylibCommand *)aDylibCommand;
{
    if ([aDylibCommand cmd] == LC_LOAD_DYLIB && [self shouldProcessRecursively] == YES)
        [self machOFileWithID:[aDylibCommand name]];
}

- (void)appendHeaderToString:(NSMutableString *)resultString;
{
    // Since this changes each version, for regression testing it'll be better to be able to not show it.
    if (flags.shouldShowHeader == NO)
        return;

    [resultString appendString:@"/*\n"];
    [resultString appendFormat:@" *     Generated by class-dump %@.\n", CLASS_DUMP_VERSION];
    [resultString appendString:@" *\n"];
    [resultString appendString:@" *     class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2006 by Steve Nygard.\n"];
    [resultString appendString:@" */\n\n"];
}

- (CDType *)typeFormatter:(CDTypeFormatter *)aFormatter replacementForType:(CDType *)aType;
{
    if ([aType type] == '{')
        return [structureTable replacementForType:aType];

    if ([aType type] == '(')
        return [unionTable replacementForType:aType];

    return nil;
}

- (NSString *)typeFormatter:(CDTypeFormatter *)aFormatter typedefNameForStruct:(CDType *)structType level:(int)level;
{
    CDType *replacementType, *searchType;
    CDStructureTable *targetTable;

    if (level == 0 && aFormatter == structDeclarationTypeFormatter)
        return nil;

    if ([structType type] == '{') {
        targetTable = structureTable;
    } else {
        targetTable = unionTable;
    }

    // We need to catch top level replacements, not just replacements for struct members.
    replacementType = [targetTable replacementForType:structType];
    if (replacementType != nil)
        searchType = replacementType;
    else
        searchType = structType;

    return [targetTable typedefNameForStructureType:searchType];
}

- (void)registerPhase:(int)phase;
{
    NSAutoreleasePool *pool;
    int count, index;

    pool = [[NSAutoreleasePool alloc] init];

    count = [objCSegmentProcessors count];
    for (index = 0; index < count; index++) {
        [[objCSegmentProcessors objectAtIndex:index] registerStructuresWithObject:self phase:phase];
    }

    [self endPhase:phase];
    [pool release];
}

- (void)endPhase:(int)phase;
{
    if (phase == 1) {
        [structureTable finishPhase1];
        [unionTable finishPhase1];
    } else if (phase == 2) {
        [structureTable generateNamesForAnonymousStructures];
        [unionTable generateNamesForAnonymousStructures];
    }
}

- (void)phase1RegisterStructure:(CDType *)aStructure;
{
    if ([aStructure type] == '{') {
        [structureTable phase1RegisterStructure:aStructure];
    } else if ([aStructure type] == '(') {
        [unionTable phase1RegisterStructure:aStructure];
    } else {
        NSLog(@"%s, unknown structure type: %d", _cmd, [aStructure type]);
    }
}

- (BOOL)phase2RegisterStructure:(CDType *)aStructure usedInMethod:(BOOL)isUsedInMethod countReferences:(BOOL)shouldCountReferences;
{
    if ([aStructure type] == '{') {
        return [structureTable phase2RegisterStructure:aStructure withObject:self usedInMethod:isUsedInMethod countReferences:shouldCountReferences];
    } else if ([aStructure type] == '(') {
        return [unionTable phase2RegisterStructure:aStructure withObject:self usedInMethod:isUsedInMethod countReferences:shouldCountReferences];
    } else {
        NSLog(@"%s, unknown structure type: %d", _cmd, [aStructure type]);
    }

    return NO;
}

- (void)generateMemberNames;
{
    [structureTable generateMemberNames];
    [unionTable generateMemberNames];
}

- (void)buildClassFrameworks;
{
    [objCSegmentProcessors makeObjectsPerformSelector:@selector(registerClassesWithObject:) withObject:frameworkNamesByClassName];
}

- (NSString *)frameworkForClassName:(NSString *)aClassName;
{
    return [frameworkNamesByClassName objectForKey:aClassName];
}

- (void)appendImportForClassName:(NSString *)aClassName toString:(NSMutableString *)resultString;
{
    if (aClassName != nil) {
        NSString *classFramework;

        classFramework = [self frameworkForClassName:aClassName];
        if (classFramework == nil)
            [resultString appendFormat:@"#import \"%@.h\"\n\n", aClassName];
        else
            [resultString appendFormat:@"#import <%@/%@.h>\n\n", classFramework, aClassName];
    }
}

@end
