// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cobalt/updater/crash_reporter.h"

#include <map>
#include <memory>
#include <vector>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/strcat.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "cobalt/updater/updater_constants.h"
// #include "cobalt/updater/updater_version.h"
#include "cobalt/updater/utils.h"
// #include "third_party/crashpad/crashpad/client/crashpad_client.h"
// #include "third_party/crashpad/crashpad/handler/handler_main.h"

namespace {

// True if the current process is connected to a crash handler process.
bool g_is_connected_to_crash_handler = false;

crashpad::CrashpadClient* GetCrashpadClient() {
  static auto* crashpad_client = new crashpad::CrashpadClient();
  return crashpad_client;
}

void RemoveSwitchIfExisting(const char* switch_to_remove,
                            std::vector<base::CommandLine::StringType>* argv) {
  const std::string pattern = base::StrCat({"--", switch_to_remove});
  auto matches_switch =
      [&pattern](const base::CommandLine::StringType& argument) -> bool {
#if defined(OS_WIN)
    return base::StartsWith(argument, base::UTF8ToUTF16(pattern),
                            base::CompareCase::SENSITIVE);
#else
    return base::StartsWith(argument, pattern, base::CompareCase::SENSITIVE);
#endif  // OS_WIN
  };
  base::EraseIf(*argv, matches_switch);
}

}  // namespace

namespace cobalt {
namespace updater {

void StartCrashReporter(const std::string& version) {
  static bool started = false;
  DCHECK(!started);
  started = true;

  base::FilePath handler_path;
  base::PathService::Get(base::FILE_EXE, &handler_path);

  base::FilePath database_path;
  if (!CreateProductDirectory(&database_path)) {
    LOG(DFATAL) << "Failed to get the database path.";
    return;
  }

  std::map<std::string, std::string> annotations;  // Crash keys.
  annotations["ver"] = version;
  annotations["prod"] = PRODUCT_FULLNAME_STRING;

  std::vector<std::string> arguments;
  arguments.push_back(base::StrCat({"--", kCrashHandlerSwitch}));

  crashpad::CrashpadClient* client = GetCrashpadClient();
  if (!client->StartHandler(handler_path, database_path,
                            /*metrics_dir=*/base::FilePath(),
                            kCrashStagingUploadURL, annotations, arguments,
                            /*restartable=*/true,
                            /*asynchronous_start=*/false)) {
    LOG(DFATAL) << "Failed to start handler.";
    return;
  }

  g_is_connected_to_crash_handler = true;
  VLOG(1) << "Crash handler launched and ready.";
}

int CrashReporterMain() {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  DCHECK(command_line->HasSwitch(kCrashHandlerSwitch));

  // Disable rate-limiting until this is fixed:
  //   https://bugs.chromium.org/p/crashpad/issues/detail?id=23
  command_line->AppendSwitch(kNoRateLimitSwitch);

  std::vector<base::CommandLine::StringType> argv = command_line->argv();

  // Because of https://bugs.chromium.org/p/crashpad/issues/detail?id=82,
  // Crashpad fails on the presence of flags it doesn't handle.
  RemoveSwitchIfExisting(kCrashHandlerSwitch, &argv);

  // |storage| must be declared before |argv_as_utf8|, to ensure it outlives
  // |argv_as_utf8|, which will hold pointers into |storage|.
  std::vector<std::string> storage;
  std::unique_ptr<char*[]> argv_as_utf8(new char*[argv.size() + 1]);
  storage.reserve(argv.size());
  for (size_t i = 0; i < argv.size(); ++i) {
#if defined(OS_WIN)
    storage.push_back(base::UTF16ToUTF8(argv[i]));
#else
    storage.push_back(argv[i]);
#endif
    argv_as_utf8[i] = &storage[i][0];
  }
  argv_as_utf8[argv.size()] = nullptr;

  return crashpad::HandlerMain(static_cast<int>(argv.size()),
                               argv_as_utf8.get(),
                               /*user_stream_sources=*/nullptr);
}

#if defined(OS_WIN)

base::string16 GetCrashReporterIPCPipeName() {
  return g_is_connected_to_crash_handler
             ? GetCrashpadClient()->GetHandlerIPCPipe()
             : base::string16();
}

void UseCrashReporter(const base::string16& ipc_pipe_name) {
  DCHECK(!ipc_pipe_name.empty());
  crashpad::CrashpadClient* crashpad_client = GetCrashpadClient();
  if (!crashpad_client->SetHandlerIPCPipe(ipc_pipe_name)) {
    LOG(DFATAL) << "Failed to set handler IPC pipe name: " << ipc_pipe_name;
    return;
  }

  g_is_connected_to_crash_handler = true;
  VLOG(1) << "Crash handler is ready.";
}

#endif  // OS_WIN

}  // namespace updater
}  // namespace cobalt
