// Copyright 2014 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <errno.h>
#include <getopt.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <map>
#include <string>
#include <vector>

#include "base/files/file_path.h"
#include "base/logging.h"
#include "build/build_config.h"
#include "client/crashpad_client.h"
#include "tools/tool_support.h"
#include "util/stdlib/map_insert.h"
#include "util/string/split_string.h"

#if BUILDFLAG(IS_FUCHSIA)
#include <lib/fdio/spawn.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>

#include "base/fuchsia/fuchsia_logging.h"
#endif

namespace crashpad {
namespace {

void Usage(const std::string& me) {
  // clang-format off
  fprintf(stderr,
"Usage: %s [OPTION]... COMMAND [ARG]...\n"
"Start a Crashpad handler and have it handle crashes from COMMAND.\n"
"\n"
  // clang-format on
#if BUILDFLAG(IS_FUCHSIA)
          // clang-format off
"COMMAND is run via fdio_spawn, so must be a qualified path to the subprocess to\n"
"be executed.\n"
  // clang-format on
#else
          // clang-format off
"COMMAND is run via execvp() so the PATH will be searched.\n"
  // clang-format on
#endif
          // clang-format off
"\n"
"  -h, --handler=HANDLER       invoke HANDLER instead of crashpad_handler\n"
"      --annotation=KEY=VALUE  passed to the handler as an --annotation argument\n"
"      --database=PATH         passed to the handler as its --database argument\n"
"      --url=URL               passed to the handler as its --url argument\n"
"  -a, --argument=ARGUMENT     invoke the handler with ARGUMENT\n"
"      --help                  display this help and exit\n"
"      --version               output version information and exit\n",
          me.c_str());
  // clang-format on
  ToolSupport::UsageTail(me);
}

int RunWithCrashpadMain(int argc, char* argv[]) {
  const std::string me(basename(argv[0]));

  enum ExitCode {
    kExitSuccess = EXIT_SUCCESS,

    // To differentiate this tool’s errors from errors in the programs it execs,
    // use a high exit code for ordinary failures instead of EXIT_FAILURE. This
    // is the same rationale for using the distinct exit codes for exec
    // failures.
    kExitFailure = 125,

    // Like env, use exit code 126 if the program was found but could not be
    // invoked, and 127 if it could not be found.
    // http://pubs.opengroup.org/onlinepubs/9699919799/utilities/env.html
    kExitExecFailure = 126,
    kExitExecENOENT = 127,
  };

  enum OptionFlags {
    // “Short” (single-character) options.
    kOptionHandler = 'h',
    kOptionArgument = 'a',

    // Long options without short equivalents.
    kOptionLastChar = 255,
    kOptionAnnotation,
    kOptionDatabase,
    kOptionURL,

    // Standard options.
    kOptionHelp = -2,
    kOptionVersion = -3,
  };

  static constexpr option long_options[] = {
      {"handler", required_argument, nullptr, kOptionHandler},
      {"annotation", required_argument, nullptr, kOptionAnnotation},
      {"database", required_argument, nullptr, kOptionDatabase},
      {"url", required_argument, nullptr, kOptionURL},
      {"argument", required_argument, nullptr, kOptionArgument},
      {"help", no_argument, nullptr, kOptionHelp},
      {"version", no_argument, nullptr, kOptionVersion},
      {nullptr, 0, nullptr, 0},
  };

  struct {
    std::string handler;
    std::map<std::string, std::string> annotations;
    std::string database;
    std::string url;
    std::vector<std::string> arguments;
  } options = {};
  options.handler = "crashpad_handler";

  int opt;
  while ((opt = getopt_long(argc, argv, "+a:h:", long_options, nullptr)) !=
         -1) {
    switch (opt) {
      case kOptionHandler: {
        options.handler = optarg;
        break;
      }
      case kOptionAnnotation: {
        std::string key;
        std::string value;
        if (!SplitStringFirst(optarg, '=', &key, &value)) {
          ToolSupport::UsageHint(me, "--annotation requires KEY=VALUE");
          return EXIT_FAILURE;
        }
        std::string old_value;
        if (!MapInsertOrReplace(&options.annotations, key, value, &old_value)) {
          LOG(WARNING) << "duplicate key " << key << ", discarding value "
                       << old_value;
        }
        break;
      }
      case kOptionDatabase: {
        options.database = optarg;
        break;
      }
      case kOptionURL: {
        options.url = optarg;
        break;
      }
      case kOptionArgument: {
        options.arguments.push_back(optarg);
        break;
      }
      case kOptionHelp: {
        Usage(me);
        return kExitSuccess;
      }
      case kOptionVersion: {
        ToolSupport::Version(me);
        return kExitSuccess;
      }
      default: {
        ToolSupport::UsageHint(me, nullptr);
        return kExitFailure;
      }
    }
  }
  argc -= optind;
  argv += optind;

  if (!argc) {
    ToolSupport::UsageHint(me, "COMMAND is required");
    return kExitFailure;
  }

  // Start the handler process and direct exceptions to it.
  CrashpadClient crashpad_client;
  if (!crashpad_client.StartHandler(base::FilePath(options.handler),
                                    base::FilePath(options.database),
                                    base::FilePath(),
                                    options.url,
                                    options.annotations,
                                    options.arguments,
                                    false,
                                    false)) {
    return kExitFailure;
  }

#if BUILDFLAG(IS_FUCHSIA)
  // Fuchsia doesn't implement execvp(), launch with fdio_spawn here.
  zx_handle_t child = ZX_HANDLE_INVALID;
  zx_status_t status = fdio_spawn(
      ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, argv[0], argv, &child);
  if (status != ZX_OK) {
    ZX_LOG(ERROR, status) << "fdio_spawn failed";
    return status == ZX_ERR_IO ? kExitExecENOENT : kExitExecFailure;
  }

  zx_signals_t observed;
  status = zx_object_wait_one(
      child, ZX_TASK_TERMINATED, ZX_TIME_INFINITE, &observed);
  if (status != ZX_OK) {
    ZX_LOG(ERROR, status) << "zx_object_wait_one";
    return kExitExecFailure;
  }
  if (!(observed & ZX_TASK_TERMINATED)) {
    LOG(ERROR) << "did not observe ZX_TASK_TERMINATED";
    return kExitExecFailure;
  }

  zx_info_process_t proc_info;
  status = zx_object_get_info(
      child, ZX_INFO_PROCESS, &proc_info, sizeof(proc_info), nullptr, nullptr);
  if (status != ZX_OK) {
    ZX_LOG(ERROR, status) << "zx_object_get_info";
    return kExitExecFailure;
  }

  return proc_info.return_code;
#else
  // Using the remaining arguments, start a new program with the new exception
  // port in effect.
  execvp(argv[0], argv);
  PLOG(ERROR) << "execvp " << argv[0];
  return errno == ENOENT ? kExitExecENOENT : kExitExecFailure;
#endif
}

}  // namespace
}  // namespace crashpad

int main(int argc, char* argv[]) {
  return crashpad::RunWithCrashpadMain(argc, argv);
}
