// 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>
#include <stdio.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"

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) {
    fprintf(stderr, "Breakpad Uploader: 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)) {
    fprintf(stderr, "Breakpad Uploader: 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) {
    fprintf(stderr, "Breakpad Uploader: Cannot find temp tar log file: %s",
            [logTarFile UTF8String]);
    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) {
    fprintf(stderr,
            "Breakpad Uploader: Renamed %s to %s after successful upload", src,
            dest);
  }
  else {
    // can't rename - don't worry - it's not important for users
    fprintf(stderr, "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
