// -*- mode: ObjC -*-

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

#import "CDObjectiveCProcessor.h"

#import "CDClassDump.h"
#import "CDMachOFile.h"
#import "CDVisitor.h"
#import "CDLCSegment.h"
#import "CDLCDynamicSymbolTable.h"
#import "CDLCSymbolTable.h"
#import "CDOCProtocol.h"
#import "CDTypeController.h"
#import "CDOCClass.h"
#import "CDOCCategory.h"
#import "CDSection.h"
#import "CDProtocolUniquer.h"

// Note: sizeof(long long) == 8 on both 32-bit and 64-bit.  sizeof(uint64_t) == 8.  So use [NSNumber numberWithUnsignedLongLong:].

@implementation CDObjectiveCProcessor
{
    CDMachOFile *_machOFile;
    
    NSMutableArray *_classes;
    NSMutableDictionary *_classesByAddress;
    
    NSMutableArray *_categories;
    
    CDProtocolUniquer *_protocolUniquer;
}

- (id)initWithMachOFile:(CDMachOFile *)machOFile;
{
    if ((self = [super init])) {
        _machOFile = machOFile;
        _classes = [[NSMutableArray alloc] init];
        _classesByAddress = [[NSMutableDictionary alloc] init];
        _categories = [[NSMutableArray alloc] init];
        
        _protocolUniquer = [[CDProtocolUniquer alloc] init];
    }

    return self;
}

#pragma mark - Debugging

- (NSString *)description;
{
    return [NSString stringWithFormat:@"<%@:%p> machOFile: %@",
            NSStringFromClass([self class]), self,
            self.machOFile.filename];
}

#pragma mark -

- (BOOL)hasObjectiveCData;
{
    return self.machOFile.hasObjectiveC1Data || self.machOFile.hasObjectiveC2Data;
}

- (CDSection *)objcImageInfoSection;
{
    // Implement in subclasses.
    return nil;
}

- (NSString *)garbageCollectionStatus;
{
    if (self.objcImageInfoSection != nil) {
        // The SDK frameworks (i.e. within Xcode, not in /System) have empty sections.
        if (self.objcImageInfoSection.size < 8)
            return @"Unknown";

        CDMachOFileDataCursor *cursor = [[CDMachOFileDataCursor alloc] initWithSection:self.objcImageInfoSection];
        
        [cursor readInt32];
        uint32_t v2 = [cursor readInt32];
        //NSLog(@"%s: %08x %08x", __cmd, v1, v2);
        // v2 == 0 -> Objective-C Garbage Collection: Unsupported
        // v2 == 2 -> Supported
        // v2 == 6 -> Required
        //NSParameterAssert(v2 == 0 || v2 == 2 || v2 == 6);
        
        // See markgc.c in the objc4 project
        switch (v2 & 0x06) {
            case 0: return @"Unsupported";
            case 2: return @"Supported";
            case 6: return @"Required";
        }
        
        return [NSString stringWithFormat:@"Unknown (0x%08x)", v2];
    }
    
    return nil;
}

#pragma mark -

- (void)addClass:(CDOCClass *)aClass withAddress:(uint64_t)address;
{
    [_classes addObject:aClass];
    [_classesByAddress setObject:aClass forKey:[NSNumber numberWithUnsignedLongLong:address]];
}

- (CDOCClass *)classWithAddress:(uint64_t)address;
{
    return [_classesByAddress objectForKey:[NSNumber numberWithUnsignedLongLong:address]];
}

- (void)addClassesFromArray:(NSArray *)array;
{
    if (array != nil)
        [_classes addObjectsFromArray:array];
}

- (void)addCategoriesFromArray:(NSArray *)array;
{
    if (array != nil)
        [_categories addObjectsFromArray:array];
}

- (void)addCategory:(CDOCCategory *)category;
{
    if (category != nil)
        [_categories addObject:category];
}

#pragma mark - Processing

- (void)process;
{
    if (self.machOFile.isEncrypted == NO && self.machOFile.canDecryptAllSegments) {
        [self.machOFile.symbolTable loadSymbols];
        [self.machOFile.dynamicSymbolTable loadSymbols];

        [self loadProtocols];
        [self.protocolUniquer createUniquedProtocols];

        // Load classes before categories, so we can get a dictionary of classes by address.
        [self loadClasses];
        [self loadCategories];
    }
}

- (void)loadProtocols;
{
    // Implement in subclasses.
}

- (void)loadClasses;
{
    // Implement in subclasses.
}

- (void)loadCategories;
{
    // Implement in subclasses.
}


- (void)registerTypesWithObject:(CDTypeController *)typeController phase:(NSUInteger)phase;
{
    for (CDOCClass *aClass in _classes)
        [aClass registerTypesWithObject:typeController phase:phase];

    for (CDOCCategory *category in _categories)
        [category registerTypesWithObject:typeController phase:phase];

    for (CDOCProtocol *protocol in [self.protocolUniquer uniqueProtocolsSortedByName])
        [protocol registerTypesWithObject:typeController phase:phase];
}

- (void)recursivelyVisit:(CDVisitor *)visitor;
{
    NSMutableArray *classesAndCategories = [[NSMutableArray alloc] init];
    [classesAndCategories addObjectsFromArray:_classes];
    [classesAndCategories addObjectsFromArray:_categories];

    [visitor willVisitObjectiveCProcessor:self];
    [visitor visitObjectiveCProcessor:self];
    
    // TODO: Sort protocols by dependency
    // TODO: (2004-01-30) It looks like protocols might be defined in more than one file.  i.e. NSObject.
    // TODO: (2004-02-02) Looks like we need to record the order the protocols were encountered, or just always sort protocols
    for (CDOCProtocol *protocol in [self.protocolUniquer uniqueProtocolsSortedByName])
        [protocol recursivelyVisit:visitor];

    if ([[visitor classDump] shouldSortClassesByInheritance]) {
        [classesAndCategories sortTopologically];
    } else if ([[visitor classDump] shouldSortClasses])
        [classesAndCategories sortUsingSelector:@selector(ascendingCompareByName:)];

    for (id aClassOrCategory in classesAndCategories)
        [aClassOrCategory recursivelyVisit:visitor];

    [visitor didVisitObjectiveCProcessor:self];
}

// Returns list of NSNumber containing the protocol addresses
- (NSArray *)protocolAddressListAtAddress:(uint64_t)address;
{
    // Implement in subclasses
    return nil;
}

@end
