// Copyright (c) 2006, 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.

#ifndef CLIENT_IOS_HANDLER_EXCEPTION_HANDLER_NO_MACH_H__
#define CLIENT_IOS_HANDLER_EXCEPTION_HANDLER_NO_MACH_H__

#include <mach/mach.h>
#include <TargetConditionals.h>

#include <string>

#include "client/mac/handler/ucontext_compat.h"
#include "common/scoped_ptr.h"

namespace google_breakpad {

using std::string;

class ExceptionHandler {
 public:
  // A callback function to run before Breakpad performs any substantial
  // processing of an exception.  A FilterCallback is called before writing
  // a minidump.  context is the parameter supplied by the user as
  // callback_context when the handler was created.
  //
  // If a FilterCallback returns true, Breakpad will continue processing,
  // attempting to write a minidump.  If a FilterCallback returns false, Breakpad
  // will immediately report the exception as unhandled without writing a
  // minidump, allowing another handler the opportunity to handle it.
  typedef bool (*FilterCallback)(void *context);

  // A callback function to run after the minidump has been written.
  // |minidump_id| is a unique id for the dump, so the minidump
  // file is <dump_dir>/<minidump_id>.dmp.
  // |context| is the value passed into the constructor.
  // |succeeded| indicates whether a minidump file was successfully written.
  // Return true if the exception was fully handled and breakpad should exit.
  // Return false to allow any other exception handlers to process the
  // exception.
  typedef bool (*MinidumpCallback)(const char *dump_dir,
                                   const char *minidump_id,
                                   void *context, bool succeeded);

  // A callback function which will be called directly if an exception occurs.
  // This bypasses the minidump file writing and simply gives the client
  // the exception information.
  typedef bool (*DirectCallback)( void *context,
                                  int exception_type,
                                  int exception_code,
                                  int exception_subcode,
                                  mach_port_t thread_name);

  // Creates a new ExceptionHandler instance to handle writing minidumps.
  // Minidump files will be written to dump_path, and the optional callback
  // is called after writing the dump file, as described above.
  // If install_handler is true, then a minidump will be written whenever
  // an unhandled exception occurs.  If it is false, minidumps will only
  // be written when WriteMinidump is called.
  // If port_name is non-NULL, attempt to perform out-of-process dump generation
  // If port_name is NULL, in-process dump generation will be used.
  ExceptionHandler(const string &dump_path,
                   FilterCallback filter, MinidumpCallback callback,
                   void *callback_context, bool install_handler,
                   const char *port_name);

  // A special constructor if we want to bypass minidump writing and
  // simply get a callback with the exception information.
  ExceptionHandler(DirectCallback callback,
                   void *callback_context,
                   bool install_handler);

  ~ExceptionHandler();

  // Get and set the minidump path.
  string dump_path() const { return dump_path_; }
  void set_dump_path(const string &dump_path) {
    dump_path_ = dump_path;
    dump_path_c_ = dump_path_.c_str();
    UpdateNextID();  // Necessary to put dump_path_ in next_minidump_path_.
  }

 private:
  // Install the SIG exception handlers.
  bool InstallHandlers();

  // Uninstall the SIG exception handlers.
  bool UninstallHandlers();

  // Setup the handler thread, and if |install_handler| is true, install the
  // mach exception port handler
  bool Setup();

  // Uninstall the mach exception handler (if any) and terminate the helper
  // thread
  bool Teardown();

  // All minidump writing goes through this one routine.
  // |task_context| can be NULL. If not, it will be used to retrieve the
  // context of the current thread, instead of using |thread_get_state|.
  bool WriteMinidumpWithException(int exception_type,
                                  int exception_code,
                                  int exception_subcode,
                                  breakpad_ucontext_t *task_context,
                                  mach_port_t thread_name,
                                  bool exit_after_write,
                                  bool report_current_thread);

  // Signal handler for SIG exceptions.
  static void SignalHandler(int sig, siginfo_t* info, void* uc);

  // disallow copy ctor and operator=
  explicit ExceptionHandler(const ExceptionHandler &);
  void operator=(const ExceptionHandler &);

  // Generates a new ID and stores it in next_minidump_id_, and stores the
  // path of the next minidump to be written in next_minidump_path_.
  void UpdateNextID();

  // The destination directory for the minidump
  string dump_path_;

  // The basename of the next minidump w/o extension
  string next_minidump_id_;

  // The full path to the next minidump to be written, including extension
  string next_minidump_path_;

  // Pointers to the UTF-8 versions of above
  const char *dump_path_c_;
  const char *next_minidump_id_c_;
  const char *next_minidump_path_c_;

  // The callback function and pointer to be passed back after the minidump
  // has been written
  FilterCallback filter_;
  MinidumpCallback callback_;
  void *callback_context_;

  // The callback function to be passed back when we don't want a minidump
  // file to be written
  DirectCallback directCallback_;

  // True, if we've installed the exception handler
  bool installed_exception_handler_;

  // True, if we're in the process of uninstalling the exception handler and
  // the thread.
  bool is_in_teardown_;
};

}  // namespace google_breakpad

#endif  // CLIENT_IOS_HANDLER_EXCEPTION_HANDLER_NO_MACH_H__
