#import "DDLog.h"

#import <pthread.h>
#import <objc/runtime.h>
#import <mach/mach_host.h>
#import <mach/host_info.h>
#import <libkern/OSAtomic.h>
#import <Availability.h>
#if TARGET_OS_IPHONE
    #import <UIKit/UIDevice.h>
#endif

/**
 * Welcome to Cocoa Lumberjack!
 * 
 * The project page has a wealth of documentation if you have any questions.
 * https://github.com/CocoaLumberjack/CocoaLumberjack
 * 
 * If you're new to the project you may wish to read the "Getting Started" wiki.
 * https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
 * 
**/

#if ! __has_feature(objc_arc)
#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
#endif

// We probably shouldn't be using DDLog() statements within the DDLog implementation.
// But we still want to leave our log statements for any future debugging,
// and to allow other developers to trace the implementation (which is a great learning tool).
// 
// So we use a primitive logging macro around NSLog.
// We maintain the NS prefix on the macros to be explicit about the fact that we're using NSLog.

#define DD_DEBUG NO

#define NSLogDebug(frmt, ...) do{ if(DD_DEBUG) NSLog((frmt), ##__VA_ARGS__); } while(0)

// Specifies the maximum queue size of the logging thread.
// 
// Since most logging is asynchronous, its possible for rogue threads to flood the logging queue.
// That is, to issue an abundance of log statements faster than the logging thread can keepup.
// Typically such a scenario occurs when log statements are added haphazardly within large loops,
// but may also be possible if relatively slow loggers are being used.
// 
// This property caps the queue size at a given number of outstanding log statements.
// If a thread attempts to issue a log statement when the queue is already maxed out,
// the issuing thread will block until the queue size drops below the max again.

#define LOG_MAX_QUEUE_SIZE 1000 // Should not exceed INT32_MAX

// The "global logging queue" refers to [DDLog loggingQueue].
// It is the queue that all log statements go through.
//
// The logging queue sets a flag via dispatch_queue_set_specific using this key.
// We can check for this key via dispatch_get_specific() to see if we're on the "global logging queue".

static void *const GlobalLoggingQueueIdentityKey = (void *)&GlobalLoggingQueueIdentityKey;


@interface DDLoggerNode : NSObject {
@public 
    id <DDLogger> logger;   
    dispatch_queue_t loggerQueue;
    int logLevel;
}

@property (nonatomic, assign, readonly) int logLevel;

+ (DDLoggerNode *)nodeWithLogger:(id <DDLogger>)logger loggerQueue:(dispatch_queue_t)loggerQueue logLevel:(int)logLevel;

@end


@interface DDLog (PrivateAPI)

+ (void)lt_addLogger:(id <DDLogger>)logger logLevel:(int)logLevel;
+ (void)lt_removeLogger:(id <DDLogger>)logger;
+ (void)lt_removeAllLoggers;
+ (NSArray *)lt_allLoggers;
+ (void)lt_log:(DDLogMessage *)logMessage;
+ (void)lt_flush;

@end

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

@implementation DDLog

// An array used to manage all the individual loggers.
// The array is only modified on the loggingQueue/loggingThread.
static NSMutableArray *loggers;

// All logging statements are added to the same queue to ensure FIFO operation.
static dispatch_queue_t loggingQueue;

// Individual loggers are executed concurrently per log statement.
// Each logger has it's own associated queue, and a dispatch group is used for synchrnoization.
static dispatch_group_t loggingGroup;

// In order to prevent to queue from growing infinitely large,
// a maximum size is enforced (LOG_MAX_QUEUE_SIZE).
static dispatch_semaphore_t queueSemaphore;

// Minor optimization for uniprocessor machines
static unsigned int numProcessors;

/**
 * The runtime sends initialize to each class in a program exactly one time just before the class,
 * or any class that inherits from it, is sent its first message from within the program. (Thus the
 * method may never be invoked if the class is not used.) The runtime sends the initialize message to
 * classes in a thread-safe manner. Superclasses receive this message before their subclasses.
 *
 * This method may also be called directly (assumably by accident), hence the safety mechanism.
**/
+ (void)initialize
{
    static dispatch_once_t DDLogOnceToken;
    dispatch_once(&DDLogOnceToken, ^{
        
        loggers = [[NSMutableArray alloc] initWithCapacity:4];
        
        NSLogDebug(@"DDLog: Using grand central dispatch");
        
        loggingQueue = dispatch_queue_create("cocoa.lumberjack", NULL);
        loggingGroup = dispatch_group_create();
        
        void *nonNullValue = GlobalLoggingQueueIdentityKey; // Whatever, just not null
        dispatch_queue_set_specific(loggingQueue, GlobalLoggingQueueIdentityKey, nonNullValue, NULL);
        
        queueSemaphore = dispatch_semaphore_create(LOG_MAX_QUEUE_SIZE);
        
        // Figure out how many processors are available.
        // This may be used later for an optimization on uniprocessor machines.
        
        host_basic_info_data_t hostInfo;
        mach_msg_type_number_t infoCount;
        
        infoCount = HOST_BASIC_INFO_COUNT;
        host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount);
        
        unsigned int result = (unsigned int)(hostInfo.max_cpus);
        unsigned int one    = (unsigned int)(1);
        
        numProcessors = MAX(result, one);
        
        NSLogDebug(@"DDLog: numProcessors = %u", numProcessors);
        
        
#if TARGET_OS_IPHONE
        NSString *notificationName = @"UIApplicationWillTerminateNotification";
#else
        NSString *notificationName = nil;
        
        // On Command Line Tool apps AppKit may not be avaliable
#ifdef NSAppKitVersionNumber10_0
        if (NSApp) {
            notificationName = @"NSApplicationWillTerminateNotification";
        }
#endif
        
        if (! notificationName)
        {
            // If there is no NSApp -> we are running Command Line Tool app.
            // In this case terminate notification wouldn't be fired, so we use workaround.
            atexit_b(^{
                [self applicationWillTerminate:nil];
            });
        }
#endif
        
        if (notificationName) {
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(applicationWillTerminate:)
                                                         name:notificationName
                                                       object:nil];
        }
        
    });
}

/**
 * Provides access to the logging queue.
**/
+ (dispatch_queue_t)loggingQueue
{
    return loggingQueue;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Notifications
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+ (void)applicationWillTerminate:(NSNotification *)notification
{
    [self flushLog];
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Logger Management
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+ (void)addLogger:(id <DDLogger>)logger
{
    [self addLogger:logger withLogLevel:LOG_LEVEL_ALL]; // LOG_LEVEL_ALL has all bits set
}

+ (void)addLogger:(id <DDLogger>)logger withLogLevel:(int)logLevel
{
    if (logger == nil) return;
    
    dispatch_async(loggingQueue, ^{ @autoreleasepool {
        
        [self lt_addLogger:logger logLevel:logLevel];
    }});
}

+ (void)removeLogger:(id <DDLogger>)logger
{
    if (logger == nil) return;
    
    dispatch_async(loggingQueue, ^{ @autoreleasepool {
        
        [self lt_removeLogger:logger];
    }});
}

+ (void)removeAllLoggers
{
    dispatch_async(loggingQueue, ^{ @autoreleasepool {
        
        [self lt_removeAllLoggers];
    }});
}

+ (NSArray *)allLoggers
{
    __block NSArray *theLoggers;

    dispatch_sync(loggingQueue, ^{ @autoreleasepool {
        theLoggers = [self lt_allLoggers];
    }});

    return theLoggers;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Master Logging
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+ (void)queueLogMessage:(DDLogMessage *)logMessage asynchronously:(BOOL)asyncFlag
{
    // We have a tricky situation here...
    // 
    // In the common case, when the queueSize is below the maximumQueueSize,
    // we want to simply enqueue the logMessage. And we want to do this as fast as possible,
    // which means we don't want to block and we don't want to use any locks.
    // 
    // However, if the queueSize gets too big, we want to block.
    // But we have very strict requirements as to when we block, and how long we block.
    // 
    // The following example should help illustrate our requirements:
    // 
    // Imagine that the maximum queue size is configured to be 5,
    // and that there are already 5 log messages queued.
    // Let us call these 5 queued log messages A, B, C, D, and E. (A is next to be executed)
    // 
    // Now if our thread issues a log statement (let us call the log message F),
    // it should block before the message is added to the queue.
    // Furthermore, it should be unblocked immediately after A has been unqueued.
    // 
    // The requirements are strict in this manner so that we block only as long as necessary,
    // and so that blocked threads are unblocked in the order in which they were blocked.
    // 
    // Returning to our previous example, let us assume that log messages A through E are still queued.
    // Our aforementioned thread is blocked attempting to queue log message F.
    // Now assume we have another separate thread that attempts to issue log message G.
    // It should block until log messages A and B have been unqueued.
    
    
    // We are using a counting semaphore provided by GCD.
    // The semaphore is initialized with our LOG_MAX_QUEUE_SIZE value.
    // Everytime we want to queue a log message we decrement this value.
    // If the resulting value is less than zero,
    // the semaphore function waits in FIFO order for a signal to occur before returning.
    // 
    // A dispatch semaphore is an efficient implementation of a traditional counting semaphore.
    // Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked.
    // If the calling semaphore does not need to block, no kernel call is made.
    
    dispatch_semaphore_wait(queueSemaphore, DISPATCH_TIME_FOREVER);
    
    // We've now sure we won't overflow the queue.
    // It is time to queue our log message.
    
    dispatch_block_t logBlock = ^{ @autoreleasepool {
        
        [self lt_log:logMessage];
    }};
    
    if (asyncFlag)
        dispatch_async(loggingQueue, logBlock);
    else
        dispatch_sync(loggingQueue, logBlock);
}

+ (void)log:(BOOL)asynchronous
      level:(int)level
       flag:(int)flag
    context:(int)context
       file:(const char *)file
   function:(const char *)function
       line:(int)line
        tag:(id)tag
     format:(NSString *)format, ...
{
    va_list args;
    if (format)
    {
        va_start(args, format);
        
        NSString *logMsg = [[NSString alloc] initWithFormat:format arguments:args];
        DDLogMessage *logMessage = [[DDLogMessage alloc] initWithLogMsg:logMsg
                                                                  level:level
                                                                   flag:flag
                                                                context:context
                                                                   file:file
                                                               function:function
                                                                   line:line
                                                                    tag:tag
                                                                options:0];
        
        [self queueLogMessage:logMessage asynchronously:asynchronous];
        
        va_end(args);
    }
}

+ (void)log:(BOOL)asynchronous
      level:(int)level
       flag:(int)flag
    context:(int)context
       file:(const char *)file
   function:(const char *)function
       line:(int)line
        tag:(id)tag
     format:(NSString *)format
       args:(va_list)args
{
    if (format)
    {
        NSString *logMsg = [[NSString alloc] initWithFormat:format arguments:args];
        DDLogMessage *logMessage = [[DDLogMessage alloc] initWithLogMsg:logMsg
                                                                  level:level
                                                                   flag:flag
                                                                context:context
                                                                   file:file
                                                               function:function
                                                                   line:line
                                                                    tag:tag
                                                                options:0];
        
        [self queueLogMessage:logMessage asynchronously:asynchronous];
    }
}

+ (void)log:(BOOL)asynchronous
    message:(DDLogMessage *)logMessage
{
    [self queueLogMessage:logMessage asynchronously:asynchronous];
}

+ (void)flushLog
{
    dispatch_sync(loggingQueue, ^{ @autoreleasepool {
        
        [self lt_flush];
    }});
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Registered Dynamic Logging
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+ (BOOL)isRegisteredClass:(Class)class
{
    SEL getterSel = @selector(ddLogLevel);
    SEL setterSel = @selector(ddSetLogLevel:);
    
#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
    
    // Issue #6 (GoogleCode) - Crashes on iOS 4.2.1 and iPhone 4
    // 
    // Crash caused by class_getClassMethod(2).
    // 
    //     "It's a bug with UIAccessibilitySafeCategory__NSObject so it didn't pop up until
    //      users had VoiceOver enabled [...]. I was able to work around it by searching the
    //      result of class_copyMethodList() instead of calling class_getClassMethod()"
    
    BOOL result = NO;
    
    unsigned int methodCount, i;
    Method *methodList = class_copyMethodList(object_getClass(class), &methodCount);
    
    if (methodList != NULL)
    {
        BOOL getterFound = NO;
        BOOL setterFound = NO;
        
        for (i = 0; i < methodCount; ++i)
        {
            SEL currentSel = method_getName(methodList[i]);
            
            if (currentSel == getterSel)
            {
                getterFound = YES;
            }
            else if (currentSel == setterSel)
            {
                setterFound = YES;
            }
            
            if (getterFound && setterFound)
            {
                result = YES;
                break;
            }
        }
        
        free(methodList);
    }
    
    return result;
    
#else
    
    // Issue #24 (GitHub) - Crashing in in ARC+Simulator
    // 
    // The method +[DDLog isRegisteredClass] will crash a project when using it with ARC + Simulator.
    // For running in the Simulator, it needs to execute the non-iOS code.
    
    Method getter = class_getClassMethod(class, getterSel);
    Method setter = class_getClassMethod(class, setterSel);
    
    if ((getter != NULL) && (setter != NULL))
    {
        return YES;
    }
    
    return NO;
    
#endif
}

+ (NSArray *)registeredClasses
{
    NSUInteger numClasses, i;
    
    // We're going to get the list of all registered classes.
    // The Objective-C runtime library automatically registers all the classes defined in your source code.
    // 
    // To do this we use the following method (documented in the Objective-C Runtime Reference):
    // 
    // int objc_getClassList(Class *buffer, int bufferLen)
    // 
    // We can pass (NULL, 0) to obtain the total number of
    // registered class definitions without actually retrieving any class definitions.
    // This allows us to allocate the minimum amount of memory needed for the application.
    
    numClasses = (NSUInteger)MAX(objc_getClassList(NULL, 0), 0);
    
    // The numClasses method now tells us how many classes we have.
    // So we can allocate our buffer, and get pointers to all the class definitions.
    
    Class *classes = numClasses ? (Class *)malloc(sizeof(Class) * numClasses) : NULL;
    if (classes == NULL) return nil;
    
    numClasses = (NSUInteger)MAX(objc_getClassList(classes, (int)numClasses), 0);
    
    // We can now loop through the classes, and test each one to see if it is a DDLogging class.
    
    NSMutableArray *result = [NSMutableArray arrayWithCapacity:numClasses];
    
    for (i = 0; i < numClasses; i++)
    {
        Class class = classes[i];
        
        if ([self isRegisteredClass:class])
        {
            [result addObject:class];
        }
    }
    
    free(classes);
    
    return result;
}

+ (NSArray *)registeredClassNames
{
    NSArray *registeredClasses = [self registeredClasses];
    NSMutableArray *result = [NSMutableArray arrayWithCapacity:[registeredClasses count]];
    
    for (Class class in registeredClasses)
    {
        [result addObject:NSStringFromClass(class)];
    }
    
    return result;
}

+ (int)logLevelForClass:(Class)aClass
{
    if ([self isRegisteredClass:aClass])
    {
        return [aClass ddLogLevel];
    }
    
    return -1;
}

+ (int)logLevelForClassWithName:(NSString *)aClassName
{
    Class aClass = NSClassFromString(aClassName);
    
    return [self logLevelForClass:aClass];
}

+ (void)setLogLevel:(int)logLevel forClass:(Class)aClass
{
    if ([self isRegisteredClass:aClass])
    {
        [aClass ddSetLogLevel:logLevel];
    }
}

+ (void)setLogLevel:(int)logLevel forClassWithName:(NSString *)aClassName
{
    Class aClass = NSClassFromString(aClassName);
    
    [self setLogLevel:logLevel forClass:aClass];
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Logging Thread
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+ (void)lt_addLogger:(id <DDLogger>)logger logLevel:(int)logLevel
{
    // Add to loggers array.
    // Need to create loggerQueue if loggerNode doesn't provide one.

    NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
            @"This method should only be run on the logging thread/queue");
    
    dispatch_queue_t loggerQueue = NULL;
    
    if ([logger respondsToSelector:@selector(loggerQueue)])
    {
        // Logger may be providing its own queue
        
        loggerQueue = [logger loggerQueue];
    }
    
    if (loggerQueue == nil)
    {
        // Automatically create queue for the logger.
        // Use the logger name as the queue name if possible.
        
        const char *loggerQueueName = NULL;
        if ([logger respondsToSelector:@selector(loggerName)])
        {
            loggerQueueName = [[logger loggerName] UTF8String];
        }
        
        loggerQueue = dispatch_queue_create(loggerQueueName, NULL);
    }
    
    DDLoggerNode *loggerNode = [DDLoggerNode nodeWithLogger:logger loggerQueue:loggerQueue logLevel:logLevel];
    [loggers addObject:loggerNode];
    
    if ([logger respondsToSelector:@selector(didAddLogger)])
    {
        dispatch_async(loggerNode->loggerQueue, ^{ @autoreleasepool {
            
            [logger didAddLogger];
        }});
    }
}

+ (void)lt_removeLogger:(id <DDLogger>)logger
{
    // Find associated loggerNode in list of added loggers

    NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
            @"This method should only be run on the logging thread/queue");
    
    DDLoggerNode *loggerNode = nil;
    
    for (DDLoggerNode *node in loggers)
    {
        if (node->logger == logger)
        {
            loggerNode = node;
            break;
        }
    }
    
    if (loggerNode == nil)
    {
        NSLogDebug(@"DDLog: Request to remove logger which wasn't added");
        return;
    }
    
    // Notify logger
    
    if ([logger respondsToSelector:@selector(willRemoveLogger)])
    {
        dispatch_async(loggerNode->loggerQueue, ^{ @autoreleasepool {
            
            [logger willRemoveLogger];
        }});
    }
    
    // Remove from loggers array
    
    [loggers removeObject:loggerNode];
}

+ (void)lt_removeAllLoggers
{
    // Notify all loggers
    
    NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
            @"This method should only be run on the logging thread/queue");

    for (DDLoggerNode *loggerNode in loggers)
    {
        if ([loggerNode->logger respondsToSelector:@selector(willRemoveLogger)])
        {
            dispatch_async(loggerNode->loggerQueue, ^{ @autoreleasepool {
                
                [loggerNode->logger willRemoveLogger];
            }});
        }
    }
    
    // Remove all loggers from array
    
    [loggers removeAllObjects];
}

+ (NSArray *)lt_allLoggers
{
    NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
            @"This method should only be run on the logging thread/queue");

    NSMutableArray *theLoggers = [NSMutableArray new];

    for (DDLoggerNode *loggerNode in loggers)
    {
        [theLoggers addObject:loggerNode->logger];
    }

    return [theLoggers copy];
}

+ (void)lt_log:(DDLogMessage *)logMessage
{
    // Execute the given log message on each of our loggers.

    NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
            @"This method should only be run on the logging thread/queue");
    
    if (numProcessors > 1)
    {
        // Execute each logger concurrently, each within its own queue.
        // All blocks are added to same group.
        // After each block has been queued, wait on group.
        // 
        // The waiting ensures that a slow logger doesn't end up with a large queue of pending log messages.
        // This would defeat the purpose of the efforts we made earlier to restrict the max queue size.
        
        for (DDLoggerNode *loggerNode in loggers)
        {
            // skip the loggers that shouldn't write this message based on the logLevel

            if (!(logMessage->logFlag & loggerNode.logLevel))
                continue;

            dispatch_group_async(loggingGroup, loggerNode->loggerQueue, ^{ @autoreleasepool {
                
                [loggerNode->logger logMessage:logMessage];
            
            }});
        }
        
        dispatch_group_wait(loggingGroup, DISPATCH_TIME_FOREVER);
    }
    else
    {
        // Execute each logger serialy, each within its own queue.
        
        for (DDLoggerNode *loggerNode in loggers)
        {
            // skip the loggers that shouldn't write this message based on the logLevel
            
            if (!(logMessage->logFlag & loggerNode.logLevel))
                continue;

            dispatch_sync(loggerNode->loggerQueue, ^{ @autoreleasepool {
                
                [loggerNode->logger logMessage:logMessage];
                
            }});
        }
    }
    
    // If our queue got too big, there may be blocked threads waiting to add log messages to the queue.
    // Since we've now dequeued an item from the log, we may need to unblock the next thread.
    
    // We are using a counting semaphore provided by GCD.
    // The semaphore is initialized with our LOG_MAX_QUEUE_SIZE value.
    // When a log message is queued this value is decremented.
    // When a log message is dequeued this value is incremented.
    // If the value ever drops below zero,
    // the queueing thread blocks and waits in FIFO order for us to signal it.
    // 
    // A dispatch semaphore is an efficient implementation of a traditional counting semaphore.
    // Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked.
    // If the calling semaphore does not need to block, no kernel call is made.
    
    dispatch_semaphore_signal(queueSemaphore);
}

+ (void)lt_flush
{
    // All log statements issued before the flush method was invoked have now been executed.
    // 
    // Now we need to propogate the flush request to any loggers that implement the flush method.
    // This is designed for loggers that buffer IO.

    NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
            @"This method should only be run on the logging thread/queue");
        
    for (DDLoggerNode *loggerNode in loggers)
    {
        if ([loggerNode->logger respondsToSelector:@selector(flush)])
        {
            dispatch_group_async(loggingGroup, loggerNode->loggerQueue, ^{ @autoreleasepool {
                
                [loggerNode->logger flush];
                
            }});
        }
    }
    
    dispatch_group_wait(loggingGroup, DISPATCH_TIME_FOREVER);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Utilities
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy)
{
    if (filePath == NULL) return nil;
    
    char *lastSlash = NULL;
    char *lastDot = NULL;
    
    char *p = (char *)filePath;
    
    while (*p != '\0')
    {
        if (*p == '/')
            lastSlash = p;
        else if (*p == '.')
            lastDot = p;
        
        p++;
    }
    
    char *subStr;
    NSUInteger subLen;
    
    if (lastSlash)
    {
        if (lastDot)
        {
            // lastSlash -> lastDot
            subStr = lastSlash + 1;
            subLen = (NSUInteger)(lastDot - subStr);
        }
        else
        {
            // lastSlash -> endOfString
            subStr = lastSlash + 1;
            subLen = (NSUInteger)(p - subStr);
        }
    }
    else
    {
        if (lastDot)
        {
            // startOfString -> lastDot
            subStr = (char *)filePath;
            subLen = (NSUInteger)(lastDot - subStr);
        }
        else
        {
            // startOfString -> endOfString
            subStr = (char *)filePath;
            subLen = (NSUInteger)(p - subStr);
        }
    }
    
    if (copy)
    {
        return [[NSString alloc] initWithBytes:subStr
                                        length:subLen
                                      encoding:NSUTF8StringEncoding];
    }
    else
    {
        // We can take advantage of the fact that __FILE__ is a string literal.
        // Specifically, we don't need to waste time copying the string.
        // We can just tell NSString to point to a range within the string literal.
        
        return [[NSString alloc] initWithBytesNoCopy:subStr
                                              length:subLen
                                            encoding:NSUTF8StringEncoding
                                        freeWhenDone:NO];
    }
}

@end

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

@implementation DDLoggerNode

@synthesize logLevel;

- (instancetype)initWithLogger:(id <DDLogger>)aLogger loggerQueue:(dispatch_queue_t)aLoggerQueue logLevel:(int)aLogLevel
{
    if ((self = [super init]))
    {
        logger = aLogger;
        
        if (aLoggerQueue) {
            loggerQueue = aLoggerQueue;
            #if !OS_OBJECT_USE_OBJC
            dispatch_retain(loggerQueue);
            #endif
        }
        logLevel = aLogLevel;
    }
    return self;
}

+ (DDLoggerNode *)nodeWithLogger:(id <DDLogger>)logger loggerQueue:(dispatch_queue_t)loggerQueue logLevel:(int)logLevel
{
    return [[DDLoggerNode alloc] initWithLogger:logger loggerQueue:loggerQueue logLevel:logLevel];
}

- (void)dealloc
{
    #if !OS_OBJECT_USE_OBJC
    if (loggerQueue) dispatch_release(loggerQueue);
    #endif
}

@end

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

@implementation DDLogMessage

static char *dd_str_copy(const char *str)
{
    if (str == NULL) return NULL;
    
    size_t length = strlen(str);
    char * result = malloc(length + 1);
    if (result == NULL) return NULL;
    strncpy(result, str, length);
    result[length] = 0;
    
    return result;
}

// Can we use DISPATCH_CURRENT_QUEUE_LABEL ?
// Can we use dispatch_get_current_queue (without it crashing) ?
//
// a) Compiling against newer SDK's (iOS 7+/OS X 10.9+) where DISPATCH_CURRENT_QUEUE_LABEL is defined
//    on a (iOS 7.0+/OS X 10.9+) runtime version
//
// b) Systems where dispatch_get_current_queue is not yet deprecated and won't crash (< iOS 6.0/OS X 10.9)
//
//    dispatch_get_current_queue(void);
//      __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6,__MAC_10_9,__IPHONE_4_0,__IPHONE_6_0)

#if TARGET_OS_IPHONE

  // Compiling for iOS

    #define USE_DISPATCH_CURRENT_QUEUE_LABEL ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
    #define USE_DISPATCH_GET_CURRENT_QUEUE ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.1)

#else

  // Compiling for Mac OS X

  #ifndef MAC_OS_X_VERSION_10_9
    #define MAC_OS_X_VERSION_10_9 1090
  #endif

  #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 // Mac OS X 10.9 or later required

    #define USE_DISPATCH_CURRENT_QUEUE_LABEL  YES
    #define USE_DISPATCH_GET_CURRENT_QUEUE    NO

  #else

    #define USE_DISPATCH_CURRENT_QUEUE_LABEL ([NSTimer instancesRespondToSelector:@selector(tolerance)]) // OS X 10.9+
    #define USE_DISPATCH_GET_CURRENT_QUEUE  (![NSTimer instancesRespondToSelector:@selector(tolerance)]) // < OS X 10.9

  #endif

#endif

- (instancetype)initWithLogMsg:(NSString *)msg
                         level:(int)level
                          flag:(int)flag
                       context:(int)context
                          file:(const char *)aFile
                      function:(const char *)aFunction
                          line:(int)line
                           tag:(id)aTag
                       options:(DDLogMessageOptions)optionsMask
{
  return [self initWithLogMsg:msg
                        level:level
                         flag:flag
                      context:context
                         file:aFile
                     function:aFunction
                         line:line
                          tag:aTag
                      options:optionsMask
                    timestamp:nil];
}

- (instancetype)initWithLogMsg:(NSString *)msg
                         level:(int)level
                          flag:(int)flag
                       context:(int)context
                          file:(const char *)aFile
                      function:(const char *)aFunction
                          line:(int)line
                           tag:(id)aTag
                       options:(DDLogMessageOptions)optionsMask
                     timestamp:(NSDate *)aTimestamp
{
  if ((self = [super init]))
  {
    logMsg     = msg;
    logLevel   = level;
    logFlag    = flag;
    logContext = context;
    lineNumber = line;
    tag        = aTag;
    options    = optionsMask;

    if (options & DDLogMessageCopyFile)
      file = dd_str_copy(aFile);
    else
      file = (char *)aFile;

    if (options & DDLogMessageCopyFunction)
      function = dd_str_copy(aFunction);
    else
      function = (char *)aFunction;

    timestamp = aTimestamp;
    if(timestamp == nil)
      timestamp = [[NSDate alloc] init];

    machThreadID = pthread_mach_thread_np(pthread_self());

    // Try to get the current queue's label

    if (USE_DISPATCH_CURRENT_QUEUE_LABEL)
	{
		queueLabel = dd_str_copy(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL));
	}
	else if (USE_DISPATCH_GET_CURRENT_QUEUE)
	{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
		dispatch_queue_t currentQueue = dispatch_get_current_queue();
#pragma clang diagnostic pop

		queueLabel = dd_str_copy(dispatch_queue_get_label(currentQueue));
	}
	else
	{
		queueLabel = dd_str_copy(""); // iOS 6.x only
	}

    threadName = [[NSThread currentThread] name];
  }
  return self;
}

- (NSString *)threadID
{
    return [[NSString alloc] initWithFormat:@"%x", machThreadID];
}

- (NSString *)fileName
{
    return DDExtractFileNameWithoutExtension(file, NO);
}

- (NSString *)methodName
{
    if (function == NULL)
        return nil;
    else
        return [[NSString alloc] initWithUTF8String:function];
}

- (void)dealloc
{
    if (file && (options & DDLogMessageCopyFile))
        free(file);

    if (function && (options & DDLogMessageCopyFunction))
        free(function);
    
    free(queueLabel);
}


- (id)copyWithZone:(NSZone *)zone {
    DDLogMessage *newMessage = [[DDLogMessage alloc] init];
    
    newMessage->logLevel = self->logLevel;
    newMessage->logFlag = self->logFlag;
    newMessage->logContext = self->logContext;
    newMessage->logMsg = self->logMsg;
    newMessage->timestamp = self->timestamp;
    
    if (self->options & DDLogMessageCopyFile) {
        newMessage->file = dd_str_copy(self->file);
        newMessage->function = dd_str_copy(self->function);
    } else {
        newMessage->file = self->file;
        newMessage->function = self->function;
    }
    
    newMessage->lineNumber = self->lineNumber;
    
    newMessage->machThreadID = self->machThreadID;
    newMessage->queueLabel = dd_str_copy(self->queueLabel);
    newMessage->threadName = self->threadName;
    newMessage->tag = self->tag;
    newMessage->options = self->options;
    
    return newMessage;
}

@end

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

@implementation DDAbstractLogger

- (id)init
{
    if ((self = [super init]))
    {
        const char *loggerQueueName = NULL;
        if ([self respondsToSelector:@selector(loggerName)])
        {
            loggerQueueName = [[self loggerName] UTF8String];
        }
        
        loggerQueue = dispatch_queue_create(loggerQueueName, NULL);
        
        // We're going to use dispatch_queue_set_specific() to "mark" our loggerQueue.
        // Later we can use dispatch_get_specific() to determine if we're executing on our loggerQueue.
        // The documentation states:
        //
        // > Keys are only compared as pointers and are never dereferenced.
        // > Thus, you can use a pointer to a static variable for a specific subsystem or
        // > any other value that allows you to identify the value uniquely.
        // > Specifying a pointer to a string constant is not recommended.
        //
        // So we're going to use the very convenient key of "self",
        // which also works when multiple logger classes extend this class, as each will have a different "self" key.
        //
        // This is used primarily for thread-safety assertions (via the isOnInternalLoggerQueue method below).
        
        void *key = (__bridge void *)self;
        void *nonNullValue = (__bridge void *)self;
        
        dispatch_queue_set_specific(loggerQueue, key, nonNullValue, NULL);
    }
    return self;
}

- (void)dealloc
{
    #if !OS_OBJECT_USE_OBJC
    if (loggerQueue) dispatch_release(loggerQueue);
    #endif
}

- (void)logMessage:(DDLogMessage *)logMessage
{
    // Override me
}

- (id <DDLogFormatter>)logFormatter
{
    // This method must be thread safe and intuitive.
    // Therefore if somebody executes the following code:
    // 
    // [logger setLogFormatter:myFormatter];
    // formatter = [logger logFormatter];
    // 
    // They would expect formatter to equal myFormatter.
    // This functionality must be ensured by the getter and setter method.
    //
    // The thread safety must not come at a cost to the performance of the logMessage method.
    // This method is likely called sporadically, while the logMessage method is called repeatedly.
    // This means, the implementation of this method:
    // - Must NOT require the logMessage method to acquire a lock.
    // - Must NOT require the logMessage method to access an atomic property (also a lock of sorts).
    //
    // Thread safety is ensured by executing access to the formatter variable on the loggerQueue.
    // This is the same queue that the logMessage method operates on.
    //
    // Note: The last time I benchmarked the performance of direct access vs atomic property access,
    // direct access was over twice as fast on the desktop and over 6 times as fast on the iPhone.
    // 
    // Furthermore, consider the following code:
    //
    // DDLogVerbose(@"log msg 1");
    // DDLogVerbose(@"log msg 2");
    // [logger setFormatter:myFormatter];
    // DDLogVerbose(@"log msg 3");
    //
    // Our intuitive requirement means that the new formatter will only apply to the 3rd log message.
    // This must remain true even when using asynchronous logging.
    // We must keep in mind the various queue's that are in play here:
    // 
    // loggerQueue : Our own private internal queue that the logMessage method runs on.
    //               Operations are added to this queue from the global loggingQueue.
    // 
    // globalLoggingQueue : The queue that all log messages go through before they arrive in our loggerQueue.
    // 
    // All log statements go through the serial gloabalLoggingQueue before they arrive at our loggerQueue.
    // Thus this method also goes through the serial globalLoggingQueue to ensure intuitive operation.
    
    // IMPORTANT NOTE:
    // 
    // Methods within the DDLogger implementation MUST access the formatter ivar directly.
    // This method is designed explicitly for external access.
    //
    // Using "self." syntax to go through this method will cause immediate deadlock.
    // This is the intended result. Fix it by accessing the ivar directly.
    // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
    
    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
    
    dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
    
    __block id <DDLogFormatter> result;
    
    dispatch_sync(globalLoggingQueue, ^{
        dispatch_sync(loggerQueue, ^{
            result = formatter;
        });
    });
    
    return result;
}

- (void)setLogFormatter:(id <DDLogFormatter>)logFormatter
{
    // The design of this method is documented extensively in the logFormatter message (above in code).
    
    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
    
    dispatch_block_t block = ^{ @autoreleasepool {
        
        if (formatter != logFormatter)
        {
            if ([formatter respondsToSelector:@selector(willRemoveFromLogger:)]) {
                [formatter willRemoveFromLogger:self];
            }
            
            formatter = logFormatter;
            
            if ([formatter respondsToSelector:@selector(didAddToLogger:)]) {
                [formatter didAddToLogger:self];
            }
        }
    }};
    
    dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
    
    dispatch_async(globalLoggingQueue, ^{
        dispatch_async(loggerQueue, block);
    });
}

- (dispatch_queue_t)loggerQueue
{
    return loggerQueue;
}

- (NSString *)loggerName
{
    return NSStringFromClass([self class]);
}

- (BOOL)isOnGlobalLoggingQueue
{
    return (dispatch_get_specific(GlobalLoggingQueueIdentityKey) != NULL);
}

- (BOOL)isOnInternalLoggerQueue
{
    void *key = (__bridge void *)self;
    return (dispatch_get_specific(key) != NULL);
}

@end
