// Copyright (c) 2011, Google 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:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * 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.
//     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
// OWNER OR 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 <fcntl.h>
#import <sys/stat.h>
#include <TargetConditionals.h>
#import <unistd.h>

#import <SystemConfiguration/SystemConfiguration.h>

#import "common/mac/HTTPMultipartUpload.h"

#import "client/apple/Framework/BreakpadDefines.h"
#import "client/mac/sender/uploader.h"
#import "common/mac/GTMLogger.h"

const int kMinidumpFileLengthLimit = 2 * 1024 * 1024;  // 2MB

#define kApplePrefsSyncExcludeAllKey \
  @"com.apple.PreferenceSync.ExcludeAllSyncKeys"

NSString *const kGoogleServerType = @"google";
NSString *const kSocorroServerType = @"socorro";
NSString *const kDefaultServerType = @"google";

#pragma mark -

namespace {
// Read one line from the configuration file.
NSString *readString(int fileId) {
  NSMutableString *str = [NSMutableString stringWithCapacity:32];
  char ch[2] = { 0 };

  while (read(fileId, &ch[0], 1) == 1) {
    if (ch[0] == '\n') {
      // Break if this is the first newline after reading some other string
      // data.
      if ([str length])
        break;
    } else {
      [str appendString:[NSString stringWithUTF8String:ch]];
    }
  }

  return str;
}

//=============================================================================
// Read |length| of binary data from the configuration file. This method will
// returns |nil| in case of error.
NSData *readData(int fileId, ssize_t length) {
  NSMutableData *data = [NSMutableData dataWithLength:length];
  char *bytes = (char *)[data bytes];

  if (read(fileId, bytes, length) != length)
    return nil;

  return data;
}

//=============================================================================
// Read the configuration from the config file.
NSDictionary *readConfigurationData(const char *configFile) {
  int fileId = open(configFile, O_RDONLY, 0600);
  if (fileId == -1) {
    GTMLoggerDebug(@"Couldn't open config file %s - %s",
                   configFile,
                   strerror(errno));
  }

  // we want to avoid a build-up of old config files even if they
  // have been incorrectly written by the framework
  if (unlink(configFile)) {
    GTMLoggerDebug(@"Couldn't unlink config file %s - %s",
                   configFile,
                   strerror(errno));
  }

  if (fileId == -1) {
    return nil;
  }

  NSMutableDictionary *config = [NSMutableDictionary dictionary];

  while (1) {
    NSString *key = readString(fileId);

    if (![key length])
      break;

    // Read the data.  Try to convert to a UTF-8 string, or just save
    // the data
    NSString *lenStr = readString(fileId);
    ssize_t len = [lenStr intValue];
    NSData *data = readData(fileId, len);
    id value = [[NSString alloc] initWithData:data
                                     encoding:NSUTF8StringEncoding];

    [config setObject:(value ? value : data) forKey:key];
    [value release];
  }

  close(fileId);
  return config;
}
}  // namespace

#pragma mark -

@interface Uploader(PrivateMethods)

// Update |parameters_| as well as the server parameters using |config|.
- (void)translateConfigurationData:(NSDictionary *)config;

// Read the minidump referenced in |parameters_| and update |minidumpContents_|
// with its content.
- (BOOL)readMinidumpData;

// Read the log files referenced in |parameters_| and update |logFileData_|
// with their content.
- (BOOL)readLogFileData;

// Returns a unique client id (user-specific), creating a persistent
// one in the user defaults, if necessary.
- (NSString*)clientID;

// Returns a dictionary that can be used to map Breakpad parameter names to
// URL parameter names.
- (NSMutableDictionary *)dictionaryForServerType:(NSString *)serverType;

// Helper method to set HTTP parameters based on server type.  This is
// called right before the upload - crashParameters will contain, on exit,
// URL parameters that should be sent with the minidump.
- (BOOL)populateServerDictionary:(NSMutableDictionary *)crashParameters;

// Initialization helper to create dictionaries mapping Breakpad
// parameters to URL parameters
- (void)createServerParameterDictionaries;

// Accessor method for the URL parameter dictionary
- (NSMutableDictionary *)urlParameterDictionary;

// Records the uploaded crash ID to the log file.
- (void)logUploadWithID:(const char *)uploadID;

// Builds an URL parameter for a given dictionary key. Uses Uploader's
// parameters to provide its value. Returns nil if no item is stored for the
// given key.
- (NSURLQueryItem *)queryItemWithName:(NSString *)queryItemName
                          forParamKey:(NSString *)key;
@end

@implementation Uploader

//=============================================================================
- (id)initWithConfigFile:(const char *)configFile {
  NSDictionary *config = readConfigurationData(configFile);
  if (!config)
    return nil;

  return [self initWithConfig:config];
}

//=============================================================================
- (id)initWithConfig:(NSDictionary *)config {
  if ((self = [super init])) {
    // Because the reporter is embedded in the framework (and many copies
    // of the framework may exist) its not completely certain that the OS
    // will obey the com.apple.PreferenceSync.ExcludeAllSyncKeys in our
    // Info.plist. To make sure, also set the key directly if needed.
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
    if (![ud boolForKey:kApplePrefsSyncExcludeAllKey]) {
      [ud setBool:YES forKey:kApplePrefsSyncExcludeAllKey];
    }

    [self createServerParameterDictionaries];

    [self translateConfigurationData:config];

    // Read the minidump into memory.
    [self readMinidumpData];
    [self readLogFileData];
  }
  return self;
}

//=============================================================================
+ (NSDictionary *)readConfigurationDataFromFile:(NSString *)configFile {
  return readConfigurationData([configFile fileSystemRepresentation]);
}

//=============================================================================
- (void)translateConfigurationData:(NSDictionary *)config {
  parameters_ = [[NSMutableDictionary alloc] init];

  NSEnumerator *it = [config keyEnumerator];
  while (NSString *key = [it nextObject]) {
    // If the keyname is prefixed by BREAKPAD_SERVER_PARAMETER_PREFIX
    // that indicates that it should be uploaded to the server along
    // with the minidump, so we treat it specially.
    if ([key hasPrefix:@BREAKPAD_SERVER_PARAMETER_PREFIX]) {
      NSString *urlParameterKey =
        [key substringFromIndex:[@BREAKPAD_SERVER_PARAMETER_PREFIX length]];
      if ([urlParameterKey length]) {
        id value = [config objectForKey:key];
        if ([value isKindOfClass:[NSString class]]) {
          [self addServerParameter:(NSString *)value
                            forKey:urlParameterKey];
        } else {
          [self addServerParameter:(NSData *)value
                            forKey:urlParameterKey];
        }
      }
    } else {
      [parameters_ setObject:[config objectForKey:key] forKey:key];
    }
  }

  // generate a unique client ID based on this host's MAC address
  // then add a key/value pair for it
  NSString *clientID = [self clientID];
  [parameters_ setObject:clientID forKey:@"guid"];
}

// Per user per machine
- (NSString *)clientID {
  NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
  NSString *crashClientID = [ud stringForKey:kClientIdPreferenceKey];
  if (crashClientID) {
    return crashClientID;
  }

  // Otherwise, if we have no client id, generate one!
  srandom((int)[[NSDate date] timeIntervalSince1970]);
  long clientId1 = random();
  long clientId2 = random();
  long clientId3 = random();
  crashClientID = [NSString stringWithFormat:@"%lx%lx%lx",
                            clientId1, clientId2, clientId3];

  [ud setObject:crashClientID forKey:kClientIdPreferenceKey];
  [ud synchronize];
  return crashClientID;
}

//=============================================================================
- (BOOL)readLogFileData {
#if TARGET_OS_IPHONE
  return NO;
#else
  unsigned int logFileCounter = 0;

  NSString *logPath;
  size_t logFileTailSize =
      [[parameters_ objectForKey:@BREAKPAD_LOGFILE_UPLOAD_SIZE] intValue];

  NSMutableArray *logFilenames; // An array of NSString, one per log file
  logFilenames = [[NSMutableArray alloc] init];

  char tmpDirTemplate[80] = "/tmp/CrashUpload-XXXXX";
  char *tmpDir = mkdtemp(tmpDirTemplate);

  // Construct key names for the keys we expect to contain log file paths
  for(logFileCounter = 0;; logFileCounter++) {
    NSString *logFileKey = [NSString stringWithFormat:@"%@%d",
                                     @BREAKPAD_LOGFILE_KEY_PREFIX,
                                     logFileCounter];

    logPath = [parameters_ objectForKey:logFileKey];

    // They should all be consecutive, so if we don't find one, assume
    // we're done

    if (!logPath) {
      break;
    }

    NSData *entireLogFile = [[NSData alloc] initWithContentsOfFile:logPath];

    if (entireLogFile == nil) {
      continue;
    }

    NSRange fileRange;

    // Truncate the log file, only if necessary

    if ([entireLogFile length] <= logFileTailSize) {
      fileRange = NSMakeRange(0, [entireLogFile length]);
    } else {
      fileRange = NSMakeRange([entireLogFile length] - logFileTailSize,
                              logFileTailSize);
    }

    char tmpFilenameTemplate[100];

    // Generate a template based on the log filename
    sprintf(tmpFilenameTemplate,"%s/%s-XXXX", tmpDir,
            [[logPath lastPathComponent] fileSystemRepresentation]);

    char *tmpFile = mktemp(tmpFilenameTemplate);

    NSData *logSubdata = [entireLogFile subdataWithRange:fileRange];
    NSString *tmpFileString = [NSString stringWithUTF8String:tmpFile];
    [logSubdata writeToFile:tmpFileString atomically:NO];

    [logFilenames addObject:[tmpFileString lastPathComponent]];
    [entireLogFile release];
  }

  if ([logFilenames count] == 0) {
    [logFilenames release];
    logFileData_ =  nil;
    return NO;
  }

  // now, bzip all files into one
  NSTask *tarTask = [[NSTask alloc] init];

  [tarTask setCurrentDirectoryPath:[NSString stringWithUTF8String:tmpDir]];
  [tarTask setLaunchPath:@"/usr/bin/tar"];

  NSMutableArray *bzipArgs = [NSMutableArray arrayWithObjects:@"-cjvf",
                                             @"log.tar.bz2",nil];
  [bzipArgs addObjectsFromArray:logFilenames];

  [logFilenames release];

  [tarTask setArguments:bzipArgs];
  [tarTask launch];
  [tarTask waitUntilExit];
  [tarTask release];

  NSString *logTarFile = [NSString stringWithFormat:@"%s/log.tar.bz2",tmpDir];
  logFileData_ = [[NSData alloc] initWithContentsOfFile:logTarFile];
  if (logFileData_ == nil) {
    GTMLoggerDebug(@"Cannot find temp tar log file: %@", logTarFile);
    return NO;
  }
  return YES;
#endif  // TARGET_OS_IPHONE
}

//=============================================================================
- (BOOL)readMinidumpData {
  NSString *minidumpDir =
      [parameters_ objectForKey:@kReporterMinidumpDirectoryKey];
  NSString *minidumpID = [parameters_ objectForKey:@kReporterMinidumpIDKey];

  if (![minidumpID length])
    return NO;

  NSString *path = [minidumpDir stringByAppendingPathComponent:minidumpID];
  path = [path stringByAppendingPathExtension:@"dmp"];

  // check the size of the minidump and limit it to a reasonable size
  // before attempting to load into memory and upload
  const char *fileName = [path fileSystemRepresentation];
  struct stat fileStatus;

  BOOL success = YES;

  if (!stat(fileName, &fileStatus)) {
    if (fileStatus.st_size > kMinidumpFileLengthLimit) {
      fprintf(stderr, "Breakpad Uploader: minidump file too large " \
              "to upload : %d\n", (int)fileStatus.st_size);
      success = NO;
    }
  } else {
      fprintf(stderr, "Breakpad Uploader: unable to determine minidump " \
              "file length\n");
      success = NO;
  }

  if (success) {
    minidumpContents_ = [[NSData alloc] initWithContentsOfFile:path];
    success = ([minidumpContents_ length] ? YES : NO);
  }

  if (!success) {
    // something wrong with the minidump file -- delete it
    unlink(fileName);
  }

  return success;
}

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

- (void)createServerParameterDictionaries {
  serverDictionary_ = [[NSMutableDictionary alloc] init];
  socorroDictionary_ = [[NSMutableDictionary alloc] init];
  googleDictionary_ = [[NSMutableDictionary alloc] init];
  extraServerVars_ = [[NSMutableDictionary alloc] init];

  [serverDictionary_ setObject:socorroDictionary_ forKey:kSocorroServerType];
  [serverDictionary_ setObject:googleDictionary_ forKey:kGoogleServerType];

  [googleDictionary_ setObject:@"ptime" forKey:@BREAKPAD_PROCESS_UP_TIME];
  [googleDictionary_ setObject:@"email" forKey:@BREAKPAD_EMAIL];
  [googleDictionary_ setObject:@"comments" forKey:@BREAKPAD_COMMENTS];
  [googleDictionary_ setObject:@"prod" forKey:@BREAKPAD_PRODUCT];
  [googleDictionary_ setObject:@"ver" forKey:@BREAKPAD_VERSION];
  [googleDictionary_ setObject:@"guid" forKey:@"guid"];

  [socorroDictionary_ setObject:@"Comments" forKey:@BREAKPAD_COMMENTS];
  [socorroDictionary_ setObject:@"CrashTime"
                         forKey:@BREAKPAD_PROCESS_CRASH_TIME];
  [socorroDictionary_ setObject:@"StartupTime"
                         forKey:@BREAKPAD_PROCESS_START_TIME];
  [socorroDictionary_ setObject:@"Version"
                         forKey:@BREAKPAD_VERSION];
  [socorroDictionary_ setObject:@"ProductName"
                         forKey:@BREAKPAD_PRODUCT];
  [socorroDictionary_ setObject:@"Email"
                         forKey:@BREAKPAD_EMAIL];
}

- (NSMutableDictionary *)dictionaryForServerType:(NSString *)serverType {
  if (serverType == nil || [serverType length] == 0) {
    return [serverDictionary_ objectForKey:kDefaultServerType];
  }
  return [serverDictionary_ objectForKey:serverType];
}

- (NSMutableDictionary *)urlParameterDictionary {
  NSString *serverType = [parameters_ objectForKey:@BREAKPAD_SERVER_TYPE];
  return [self dictionaryForServerType:serverType];

}

- (BOOL)populateServerDictionary:(NSMutableDictionary *)crashParameters {
  NSDictionary *urlParameterNames = [self urlParameterDictionary];

  id key;
  NSEnumerator *enumerator = [parameters_ keyEnumerator];

  while ((key = [enumerator nextObject])) {
    // The key from parameters_ corresponds to a key in
    // urlParameterNames.  The value in parameters_ gets stored in
    // crashParameters with a key that is the value in
    // urlParameterNames.

    // For instance, if parameters_ has [PRODUCT_NAME => "FOOBAR"] and
    // urlParameterNames has [PRODUCT_NAME => "pname"] the final HTTP
    // URL parameter becomes [pname => "FOOBAR"].
    NSString *breakpadParameterName = (NSString *)key;
    NSString *urlParameter = [urlParameterNames
                                   objectForKey:breakpadParameterName];
    if (urlParameter) {
      [crashParameters setObject:[parameters_ objectForKey:key]
                          forKey:urlParameter];
    }
  }

  // Now, add the parameters that were added by the application.
  enumerator = [extraServerVars_ keyEnumerator];

  while ((key = [enumerator nextObject])) {
    NSString *urlParameterName = (NSString *)key;
    NSString *urlParameterValue =
      [extraServerVars_ objectForKey:urlParameterName];
    [crashParameters setObject:urlParameterValue
                        forKey:urlParameterName];
  }
  return YES;
}

- (void)addServerParameter:(id)value forKey:(NSString *)key {
  [extraServerVars_ setObject:value forKey:key];
}

//=============================================================================
- (void)handleNetworkResponse:(NSData *)data withError:(NSError *)error {
  NSString *result = [[NSString alloc] initWithData:data
                                           encoding:NSUTF8StringEncoding];
  const char *reportID = "ERR";
  if (error) {
    fprintf(stderr, "Breakpad Uploader: Send Error: %s\n",
            [[error description] UTF8String]);
  } else {
    NSCharacterSet *trimSet =
        [NSCharacterSet whitespaceAndNewlineCharacterSet];
    reportID = [[result stringByTrimmingCharactersInSet:trimSet] UTF8String];
    [self logUploadWithID:reportID];
  }
  if (uploadCompletion_) {
    uploadCompletion_([NSString stringWithUTF8String:reportID], error);
  }

  // rename the minidump file according to the id returned from the server
  NSString *minidumpDir =
      [parameters_ objectForKey:@kReporterMinidumpDirectoryKey];
  NSString *minidumpID = [parameters_ objectForKey:@kReporterMinidumpIDKey];

  NSString *srcString = [NSString stringWithFormat:@"%@/%@.dmp",
                                  minidumpDir, minidumpID];
  NSString *destString = [NSString stringWithFormat:@"%@/%s.dmp",
                                   minidumpDir, reportID];

  const char *src = [srcString fileSystemRepresentation];
  const char *dest = [destString fileSystemRepresentation];

  if (rename(src, dest) == 0) {
    GTMLoggerInfo(@"Breakpad Uploader: Renamed %s to %s after successful " \
                  "upload",src, dest);
  }
  else {
    // can't rename - don't worry - it's not important for users
    GTMLoggerDebug(@"Breakpad Uploader: successful upload report ID = %s\n",
                   reportID );
  }
  [result release];
}

//=============================================================================
- (NSURLQueryItem *)queryItemWithName:(NSString *)queryItemName
                          forParamKey:(NSString *)key {
  NSString *value = [parameters_ objectForKey:key];
  NSString *escapedValue =
    [value stringByAddingPercentEncodingWithAllowedCharacters:
      [NSCharacterSet URLQueryAllowedCharacterSet]];
  return [NSURLQueryItem queryItemWithName:queryItemName value:escapedValue];
}

//=============================================================================
- (void)setUploadCompletionBlock:(UploadCompletionBlock)uploadCompletion {
  uploadCompletion_ = uploadCompletion;
}

//=============================================================================
- (void)report {
  NSURL *url = [NSURL URLWithString:[parameters_ objectForKey:@BREAKPAD_URL]];

  NSString *serverType = [parameters_ objectForKey:@BREAKPAD_SERVER_TYPE];
  if ([serverType length] == 0 ||
      [serverType isEqualToString:kGoogleServerType]) {
    // when communicating to Google's crash collecting service, add URL params
    // which identify the product
    NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url
                                                resolvingAgainstBaseURL:false];
    NSMutableArray *queryItemsToAdd = [urlComponents.queryItems mutableCopy];
    if (queryItemsToAdd == nil) {
      queryItemsToAdd = [[NSMutableArray alloc] init];
    }

    NSURLQueryItem *queryItemProduct =
      [self queryItemWithName:@"product" forParamKey:@BREAKPAD_PRODUCT];
    NSURLQueryItem *queryItemVersion =
      [self queryItemWithName:@"version" forParamKey:@BREAKPAD_VERSION];
    NSURLQueryItem *queryItemGuid =
      [self queryItemWithName:@"guid" forParamKey:@"guid"];

    if (queryItemProduct != nil) [queryItemsToAdd addObject:queryItemProduct];
    if (queryItemVersion != nil) [queryItemsToAdd addObject:queryItemVersion];
    if (queryItemGuid != nil) [queryItemsToAdd addObject:queryItemGuid];

    urlComponents.queryItems = queryItemsToAdd;
    url = [urlComponents URL];
  }

  HTTPMultipartUpload *upload = [[HTTPMultipartUpload alloc] initWithURL:url];
  NSMutableDictionary *uploadParameters = [NSMutableDictionary dictionary];

  if (![self populateServerDictionary:uploadParameters]) {
    [upload release];
    return;
  }

  [upload setParameters:uploadParameters];

  // Add minidump file
  if (minidumpContents_) {
    [upload addFileContents:minidumpContents_ name:@"upload_file_minidump"];

    // If there is a log file, upload it together with the minidump.
    if (logFileData_) {
      [upload addFileContents:logFileData_ name:@"log"];
    }

    // Send it
    NSError *error = nil;
    NSData *data = [upload send:&error];

    if (![url isFileURL]) {
      [self handleNetworkResponse:data withError:error];
    } else {
      if (error) {
        fprintf(stderr, "Breakpad Uploader: Error writing request file: %s\n",
                [[error description] UTF8String]);
      }
    }

  } else {
    // Minidump is missing -- upload just the log file.
    if (logFileData_) {
      [self uploadData:logFileData_ name:@"log"];
    }
  }
  [upload release];
}

- (void)uploadData:(NSData *)data name:(NSString *)name {
  NSURL *url = [NSURL URLWithString:[parameters_ objectForKey:@BREAKPAD_URL]];
  NSMutableDictionary *uploadParameters = [NSMutableDictionary dictionary];

  if (![self populateServerDictionary:uploadParameters])
    return;

  HTTPMultipartUpload *upload =
      [[HTTPMultipartUpload alloc] initWithURL:url];

  [uploadParameters setObject:name forKey:@"type"];
  [upload setParameters:uploadParameters];
  [upload addFileContents:data name:name];

  [upload send:nil];
  [upload release];
}

- (void)logUploadWithID:(const char *)uploadID {
  NSString *minidumpDir =
      [parameters_ objectForKey:@kReporterMinidumpDirectoryKey];
  NSString *logFilePath = [NSString stringWithFormat:@"%@/%s",
      minidumpDir, kReporterLogFilename];
  NSString *logLine = [NSString stringWithFormat:@"%0.f,%s\n",
      [[NSDate date] timeIntervalSince1970], uploadID];
  NSData *logData = [logLine dataUsingEncoding:NSUTF8StringEncoding];

  NSFileManager *fileManager = [NSFileManager defaultManager];
  if ([fileManager fileExistsAtPath:logFilePath]) {
    NSFileHandle *logFileHandle =
       [NSFileHandle fileHandleForWritingAtPath:logFilePath];
    [logFileHandle seekToEndOfFile];
    [logFileHandle writeData:logData];
    [logFileHandle closeFile];
  } else {
    [fileManager createFileAtPath:logFilePath
                         contents:logData
                       attributes:nil];
  }
}

//=============================================================================
- (NSMutableDictionary *)parameters {
  return parameters_;
}

//=============================================================================
- (void)dealloc {
  [parameters_ release];
  [minidumpContents_ release];
  [logFileData_ release];
  [googleDictionary_ release];
  [socorroDictionary_ release];
  [serverDictionary_ release];
  [extraServerVars_ release];
  [super dealloc];
}

@end
