// 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.

// Framework to provide a simple C API to crash reporting for
// applications.  By default, if any machine-level exception (e.g.,
// EXC_BAD_ACCESS) occurs, it will be handled by the BreakpadRef
// object as follows:
//
// 1. Create a minidump file (see Breakpad for details)
// 2. Create a config file.
//
// These files can then be uploaded to a server.

typedef void *BreakpadRef;

#ifdef __cplusplus
extern "C" {
#endif

#include <Foundation/Foundation.h>

#include <client/apple/Framework/BreakpadDefines.h>

// The keys in the dictionary returned by |BreakpadGenerateReport|.
#define BREAKPAD_OUTPUT_DUMP_FILE   "BreakpadDumpFile"
#define BREAKPAD_OUTPUT_CONFIG_FILE "BreakpadConfigFile"

// Optional user-defined function to decide if we should handle this crash or
// forward it along.
// Return true if you want Breakpad to handle it.
// Return false if you want Breakpad to skip it
// The exception handler always returns false, as if SEND_AND_EXIT were false
// (which means the next exception handler will take the exception)
typedef bool (*BreakpadFilterCallback)(int exception_type,
                                       int exception_code,
                                       mach_port_t crashing_thread,
                                       void *context);

// Create a new BreakpadRef object and install it as an exception
// handler.  The |parameters| will typically be the contents of your
// bundle's Info.plist.
//
// You can also specify these additional keys for customizable behavior:
// Key:                           Value:
// BREAKPAD_PRODUCT               Product name (e.g., "MyAwesomeProduct")
//                                This one is used as the key to identify
//                                the product when uploading. Falls back to
//                                CFBundleName if not specified.
//                                REQUIRED
//
// BREAKPAD_PRODUCT_DISPLAY       This is the display name, e.g. a pretty
//                                name for the product when the crash_sender
//                                pops up UI for the user. Falls back first to
//                                CFBundleDisplayName and then to
//                                BREAKPAD_PRODUCT if not specified.
//
// BREAKPAD_VERSION               Product version (e.g., 1.2.3), used
//                                as metadata for crash report. Falls back to
//                                CFBundleVersion if not specified.
//                                REQUIRED
//
// BREAKPAD_VENDOR                Vendor name, used in UI (e.g. "A report has
//                                been created that you can send to <vendor>")
//
// BREAKPAD_URL                   URL destination for reporting
//                                REQUIRED
//
// BREAKPAD_DUMP_DIRECTORY        The directory to store crash-dumps
//                                in. By default, we use
//                                ~/Library/Cache/Breakpad/<BREAKPAD_PRODUCT>
//                                The path you specify here is tilde-expanded.
//
// BREAKPAD_SERVER_TYPE           A parameter that tells Breakpad how to
//                                rewrite the upload parameters for a specific
//                                server type.  The currently valid values are
//                                'socorro' or 'google'.  If you want to add
//                                other types, see the function in
//                                crash_report_sender.m that maps parameters to
//                                URL parameters.  Defaults to 'google'.
//
// BREAKPAD_SERVER_PARAMETER_DICT A plist dictionary of static
//                                parameters that are uploaded to the
//                                server.  The parameters are sent as
//                                is to the crash server.  Their
//                                content isn't added to the minidump
//                                but pass as URL parameters when
//                                uploading theminidump to the crash
//                                server.
//=============================================================================
// The BREAKPAD_PRODUCT, BREAKPAD_VERSION and BREAKPAD_URL are
// required to have non-NULL values.  By default, the BREAKPAD_PRODUCT
// will be the CFBundleName and the BREAKPAD_VERSION will be the
// CFBundleVersion when these keys are present in the bundle's
// Info.plist, which is usually passed in to BreakpadCreate() as an
// NSDictionary (you could also pass in another dictionary that had
// the same keys configured).  If the BREAKPAD_PRODUCT or
// BREAKPAD_VERSION are ultimately undefined, BreakpadCreate() will
// fail.  You have been warned.
//
// If you are running in a debugger, Breakpad will not install, unless the
// BREAKPAD_IGNORE_DEBUGGER envionment variable is set and/or non-zero.
//
//=============================================================================
// The following are NOT user-supplied but are documented here for
// completeness.  They are calculated by Breakpad during initialization &
// crash-dump generation, or entered in by the user.
//
// BREAKPAD_PROCESS_START_TIME       The time, in seconds since the Epoch, the
//                                   process started
//
// BREAKPAD_PROCESS_CRASH_TIME       The time, in seconds since the Epoch, the
//                                   process crashed.
//
// BREAKPAD_PROCESS_UP_TIME          The total time in milliseconds the process
//                                   has been running.  This parameter is not
//                                   set until the crash-dump-generation phase.
//
// BREAKPAD_SERVER_PARAMETER_PREFIX  This prefix is used by Breakpad
//                                   internally, because Breakpad uses
//                                   the same dictionary internally to
//                                   track both its internal
//                                   configuration parameters and
//                                   parameters meant to be uploaded
//                                   to the server.  This string is
//                                   used internally by Breakpad to
//                                   prefix user-supplied parameter
//                                   names so those can be sent to the
//                                   server without leaking Breakpad's
//                                   internal values.

// Returns a new BreakpadRef object on success, NULL otherwise.
BreakpadRef BreakpadCreate(NSDictionary *parameters);

// Uninstall and release the data associated with |ref|.
void BreakpadRelease(BreakpadRef ref);

// User defined key and value string storage.  Generally this is used
// to configure Breakpad's internal operation, such as whether the
// crash_sender should prompt the user, or the filesystem location for
// the minidump file.  See Breakpad.h for some parameters that can be
// set.  Anything longer than 255 bytes will be truncated. Note that
// the string is converted to UTF8 before truncation, so any multibyte
// character that straddles the 255(256 - 1 for terminator) byte limit
// will be mangled.
//
// A maximum number of 64 key/value pairs are supported.  An assert()
// will fire if more than this number are set.  Unfortunately, right
// now, the same dictionary is used for both Breakpad's parameters AND
// the Upload parameters.
//
// TODO (nealsid): Investigate how necessary this is if we don't
// automatically upload parameters to the server anymore.
// TODO (nealsid): separate server parameter dictionary from the
// dictionary used to configure Breakpad, and document limits for each
// independently.
void BreakpadSetKeyValue(BreakpadRef ref, NSString *key, NSString *value);
NSString *BreakpadKeyValue(BreakpadRef ref, NSString *key);
void BreakpadRemoveKeyValue(BreakpadRef ref, NSString *key);

// You can use this method to specify parameters that will be uploaded
// to the crash server.  They will be automatically encoded as
// necessary.  Note that as mentioned above there are limits on both
// the number of keys and their length.
void BreakpadAddUploadParameter(BreakpadRef ref, NSString *key,
                                NSString *value);

// This method will remove a previously-added parameter from the
// upload parameter set.
void BreakpadRemoveUploadParameter(BreakpadRef ref, NSString *key);

// Method to handle uploading data to the server

// Returns the number of crash reports waiting to send to the server.
int BreakpadGetCrashReportCount(BreakpadRef ref);

// Returns the next upload configuration. The report file is deleted.
NSDictionary *BreakpadGetNextReportConfiguration(BreakpadRef ref);

// Upload next report to the server.
void BreakpadUploadNextReport(BreakpadRef ref);

// Upload next report to the server.
// |server_parameters| is additional server parameters to send.
void BreakpadUploadNextReportWithParameters(BreakpadRef ref,
                                            NSDictionary *server_parameters);

// Upload a report to the server.
// |server_parameters| is additional server parameters to send.
// |configuration| is the configuration of the breakpad report to send.
void BreakpadUploadReportWithParametersAndConfiguration(
    BreakpadRef ref,
    NSDictionary *server_parameters,
    NSDictionary *configuration);

// Handles the network response of a breakpad upload. This function is needed if
// the actual upload is done by the Breakpad client.
// |configuration| is the configuration of the upload. It must contain the same
// fields as the configuration passed to
// BreakpadUploadReportWithParametersAndConfiguration.
// |data| and |error| contain the network response.
void BreakpadHandleNetworkResponse(BreakpadRef ref,
                                   NSDictionary *configuration,
                                   NSData *data,
                                   NSError *error);

// Upload a file to the server. |data| is the content of the file to sent.
// |server_parameters| is additional server parameters to send.
void BreakpadUploadData(BreakpadRef ref, NSData *data, NSString *name,
                        NSDictionary *server_parameters);

// Generate a breakpad minidump and configuration file in the dump directory.
// The report will be available for uploading. The paths of the created files
// are returned in the dictionary. |server_parameters| is additional server
// parameters to add in the config file.
NSDictionary *BreakpadGenerateReport(BreakpadRef ref,
                                     NSDictionary *server_parameters);

#ifdef __cplusplus
}
#endif
