// Copyright (c) 2012, 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 "BreakpadController.h"

#import <UIKit/UIKit.h>
#include <asl.h>
#include <execinfo.h>
#include <signal.h>
#include <unistd.h>
#include <sys/sysctl.h>

#include <common/scoped_ptr.h>

#pragma mark -
#pragma mark Private Methods

@interface BreakpadController ()

// Init the singleton instance.
- (id)initSingleton;

// Load a crash report and send it to the server.
- (void)sendStoredCrashReports;

// Returns when a report can be sent. |-1| means never, |0| means that a report
// can be sent immediately, a positive number is the number of seconds to wait
// before being allowed to upload a report.
- (int)sendDelay;

// Notifies that a report will be sent, and update the last sending time
// accordingly.
- (void)reportWillBeSent;

@end

#pragma mark -
#pragma mark Anonymous namespace

namespace {

// The name of the user defaults key for the last submission to the crash
// server.
NSString* const kLastSubmission = @"com.google.Breakpad.LastSubmission";

// Returns a NSString describing the current platform.
NSString* GetPlatform() {
  // Name of the system call for getting the platform.
  static const char kHwMachineSysctlName[] = "hw.machine";

  NSString* result = nil;

  size_t size = 0;
  if (sysctlbyname(kHwMachineSysctlName, NULL, &size, NULL, 0) || size == 0)
    return nil;
  google_breakpad::scoped_array<char> machine(new char[size]);
  if (sysctlbyname(kHwMachineSysctlName, machine.get(), &size, NULL, 0) == 0)
    result = [NSString stringWithUTF8String:machine.get()];
  return result;
}

}  // namespace

#pragma mark -
#pragma mark BreakpadController Implementation

@implementation BreakpadController

+ (BreakpadController*)sharedInstance {
  static dispatch_once_t onceToken;
  static BreakpadController* sharedInstance ;
  dispatch_once(&onceToken, ^{
      sharedInstance = [[BreakpadController alloc] initSingleton];
  });
  return sharedInstance;
}

- (id)init {
  return nil;
}

- (id)initSingleton {
  self = [super init];
  if (self) {
    queue_ = dispatch_queue_create("com.google.BreakpadQueue", NULL);
    enableUploads_ = NO;
    started_ = NO;
    [self resetConfiguration];
  }
  return self;
}

// Since this class is a singleton, this method is not expected to be called.
- (void)dealloc {
  assert(!breakpadRef_);
  dispatch_release(queue_);
  [configuration_ release];
  [uploadTimeParameters_ release];
  [super dealloc];
}

#pragma mark -

- (void)start:(BOOL)onCurrentThread {
  if (started_)
    return;
  started_ = YES;
  void(^startBlock)() = ^{
      assert(!breakpadRef_);
      breakpadRef_ = BreakpadCreate(configuration_);
      if (breakpadRef_) {
        BreakpadAddUploadParameter(breakpadRef_, @"platform", GetPlatform());
      }
  };
  if (onCurrentThread)
    startBlock();
  else
    dispatch_async(queue_, startBlock);
}

- (void)stop {
  if (!started_)
    return;
  started_ = NO;
  dispatch_sync(queue_, ^{
      if (breakpadRef_) {
        BreakpadRelease(breakpadRef_);
        breakpadRef_ = NULL;
      }
  });
}

- (BOOL)isStarted {
  return started_;
}

// This method must be called from the breakpad queue.
- (void)threadUnsafeSendReportWithConfiguration:(NSDictionary*)configuration
                                withBreakpadRef:(BreakpadRef)ref {
  NSAssert(started_, @"The controller must be started before "
                     "threadUnsafeSendReportWithConfiguration is called");
  if (breakpadRef_) {
    BreakpadUploadReportWithParametersAndConfiguration(breakpadRef_,
                                                       uploadTimeParameters_,
                                                       configuration);
  }
}

- (void)setUploadingEnabled:(BOOL)enabled {
  NSAssert(started_,
      @"The controller must be started before setUploadingEnabled is called");
  dispatch_async(queue_, ^{
      if (enabled == enableUploads_)
        return;
      if (enabled) {
        // Set this before calling doSendStoredCrashReport, because that
        // calls sendDelay, which in turn checks this flag.
        enableUploads_ = YES;
        [self sendStoredCrashReports];
      } else {
        // disable the enableUpload_ flag.
        // sendDelay checks this flag and disables the upload of logs by sendStoredCrashReports
        enableUploads_ = NO;
      }
  });
}

- (void)updateConfiguration:(NSDictionary*)configuration {
  NSAssert(!started_,
      @"The controller must not be started when updateConfiguration is called");
  [configuration_ addEntriesFromDictionary:configuration];
  NSString* uploadInterval =
      [configuration_ valueForKey:@BREAKPAD_REPORT_INTERVAL];
  if (uploadInterval)
    [self setUploadInterval:[uploadInterval intValue]];
}

- (void)resetConfiguration {
  NSAssert(!started_,
      @"The controller must not be started when resetConfiguration is called");
  [configuration_ autorelease];
  configuration_ = [[[NSBundle mainBundle] infoDictionary] mutableCopy];
  NSString* uploadInterval =
      [configuration_ valueForKey:@BREAKPAD_REPORT_INTERVAL];
  [self setUploadInterval:[uploadInterval intValue]];
  [self setParametersToAddAtUploadTime:nil];
}

- (void)setUploadingURL:(NSString*)url {
  NSAssert(!started_,
      @"The controller must not be started when setUploadingURL is called");
  [configuration_ setValue:url forKey:@BREAKPAD_URL];
}

- (void)setUploadInterval:(int)intervalInSeconds {
  NSAssert(!started_,
      @"The controller must not be started when setUploadInterval is called");
  [configuration_ removeObjectForKey:@BREAKPAD_REPORT_INTERVAL];
  uploadIntervalInSeconds_ = intervalInSeconds;
  if (uploadIntervalInSeconds_ < 0)
    uploadIntervalInSeconds_ = 0;
}

- (void)setParametersToAddAtUploadTime:(NSDictionary*)uploadTimeParameters {
  NSAssert(!started_, @"The controller must not be started when "
                      "setParametersToAddAtUploadTime is called");
  [uploadTimeParameters_ autorelease];
  uploadTimeParameters_ = [uploadTimeParameters copy];
}

- (void)addUploadParameter:(NSString*)value forKey:(NSString*)key {
  NSAssert(started_,
      @"The controller must be started before addUploadParameter is called");
  dispatch_async(queue_, ^{
      if (breakpadRef_)
        BreakpadAddUploadParameter(breakpadRef_, key, value);
  });
}

- (void)removeUploadParameterForKey:(NSString*)key {
  NSAssert(started_, @"The controller must be started before "
                     "removeUploadParameterForKey is called");
  dispatch_async(queue_, ^{
      if (breakpadRef_)
        BreakpadRemoveUploadParameter(breakpadRef_, key);
  });
}

- (void)withBreakpadRef:(void(^)(BreakpadRef))callback {
  dispatch_async(queue_, ^{
      callback(started_ ? breakpadRef_ : NULL);
  });
}

- (void)hasReportToUpload:(void(^)(BOOL))callback {
  NSAssert(started_, @"The controller must be started before "
                     "hasReportToUpload is called");
  dispatch_async(queue_, ^{
      callback(breakpadRef_ && (BreakpadGetCrashReportCount(breakpadRef_) > 0));
  });
}

- (void)getCrashReportCount:(void(^)(int))callback {
  NSAssert(started_, @"The controller must be started before "
                     "getCrashReportCount is called");
  dispatch_async(queue_, ^{
      callback(breakpadRef_ ? BreakpadGetCrashReportCount(breakpadRef_) : 0);
  });
}

- (void)getNextReportConfigurationOrSendDelay:
    (void(^)(NSDictionary*, int))callback {
  NSAssert(started_, @"The controller must be started before "
                     "getNextReportConfigurationOrSendDelay is called");
  dispatch_async(queue_, ^{
      if (!breakpadRef_) {
        callback(nil, -1);
        return;
      }
      int delay = [self sendDelay];
      if (delay != 0) {
        callback(nil, delay);
        return;
      }
      [self reportWillBeSent];
      callback(BreakpadGetNextReportConfiguration(breakpadRef_), 0);
  });
}

- (void)getDateOfMostRecentCrashReport:(void(^)(NSDate *))callback {
  NSAssert(started_, @"The controller must be started before "
           "getDateOfMostRecentCrashReport is called");
  dispatch_async(queue_, ^{
    if (!breakpadRef_) {
      callback(nil);
      return;
    }
    callback(BreakpadGetDateOfMostRecentCrashReport(breakpadRef_));
  });
}

#pragma mark -

- (int)sendDelay {
  if (!breakpadRef_ || uploadIntervalInSeconds_ <= 0 || !enableUploads_)
    return -1;

  // To prevent overloading the crash server, crashes are not sent than one
  // report every |uploadIntervalInSeconds_|. A value in the user defaults is
  // used to keep the time of the last upload.
  NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  NSNumber *lastTimeNum = [userDefaults objectForKey:kLastSubmission];
  NSTimeInterval lastTime = lastTimeNum ? [lastTimeNum floatValue] : 0;
  NSTimeInterval spanSeconds = CFAbsoluteTimeGetCurrent() - lastTime;

  if (spanSeconds >= uploadIntervalInSeconds_)
    return 0;
  return uploadIntervalInSeconds_ - static_cast<int>(spanSeconds);
}

- (void)reportWillBeSent {
  NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  [userDefaults setObject:[NSNumber numberWithDouble:CFAbsoluteTimeGetCurrent()]
                   forKey:kLastSubmission];
  [userDefaults synchronize];
}

// This method must be called from the breakpad queue.
- (void)sendStoredCrashReports {
  if (BreakpadGetCrashReportCount(breakpadRef_) == 0)
    return;

  int timeToWait = [self sendDelay];

  // Unable to ever send report.
  if (timeToWait == -1)
    return;

  // A report can be sent now.
  if (timeToWait == 0) {
    [self reportWillBeSent];
    BreakpadUploadNextReportWithParameters(breakpadRef_,
                                           uploadTimeParameters_);

    // If more reports must be sent, make sure this method is called again.
    if (BreakpadGetCrashReportCount(breakpadRef_) > 0)
      timeToWait = uploadIntervalInSeconds_;
  }

  // A report must be sent later.
  if (timeToWait > 0) {
    dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeToWait * NSEC_PER_SEC));
    dispatch_after(delay, queue_, ^{
        [self sendStoredCrashReports];
    });
  }
}

@end
