// Copyright (c) 2012 The Chromium OS 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 <fcntl.h>      // for open
#include <sys/mount.h>  // for MS_SLAVE

#include <string>
#include <utility>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/callback.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/strings/stringprintf.h>
#include <base/task/single_thread_task_executor.h>
#include <base/optional.h>
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>
#include <libminijail.h>
#include <metrics/metrics_library.h>

#include "crash-reporter/arc_collector.h"
#include "crash-reporter/arc_util.h"
#include "crash-reporter/arcvm_kernel_collector.h"
#include "crash-reporter/arcvm_native_collector.h"
#include "crash-reporter/bert_collector.h"
#include "crash-reporter/chrome_collector.h"
#include "crash-reporter/constants.h"
#include "crash-reporter/crash_reporter_failure_collector.h"
#include "crash-reporter/ec_collector.h"
#include "crash-reporter/ephemeral_crash_collector.h"
#include "crash-reporter/generic_failure_collector.h"
#include "crash-reporter/kernel_collector.h"
#include "crash-reporter/kernel_warning_collector.h"
#include "crash-reporter/missed_crash_collector.h"
#include "crash-reporter/mount_failure_collector.h"
#include "crash-reporter/paths.h"
#include "crash-reporter/selinux_violation_collector.h"
#include "crash-reporter/udev_collector.h"
#include "crash-reporter/unclean_shutdown_collector.h"
#include "crash-reporter/user_collector.h"
#include "crash-reporter/util.h"
#include "crash-reporter/vm_collector.h"

using base::FilePath;
using base::StringPrintf;

namespace {

const char kKernelCrashDetected[] =
    "/run/metrics/external/crash-reporter/kernel-crash-detected";
const char kUncleanShutdownDetected[] =
    "/run/metrics/external/crash-reporter/unclean-shutdown-detected";
const char kBootCollectorDone[] = "/run/crash_reporter/boot-collector-done";

// Used for consent verification.
// TODO(mutexlox): Declare this in main and plumb it through via parameters.
MetricsLibrary s_metrics_lib;

bool TouchFile(const FilePath& file_path) {
  return base::WriteFile(file_path, "", 0) == 0;
}

bool SetUpLockFile() {
  base::FilePath lock_file = paths::Get(paths::kCrashSenderLockFile);
  if (!TouchFile(lock_file)) {
    LOG(ERROR) << "Could not touch lock file: " << lock_file.value();
    return false;
  }

  // Allow crash-access group to read and write crash lock file.
  return util::SetGroupAndPermissions(lock_file, constants::kCrashGroupName,
                                      /*execute=*/false);
}

// Set up necessary crash reporter state.
// This function will change ownership and permissions on many files (to allow
// `crash` to read/write them) so it MUST run as root.
// Return true on success.
bool InitializeSystem(UserCollector* user_collector, bool early) {
  // Try to create the lock file for crash_sender. Creating this early ensures
  // that no one else can make a directory or such with this name. If the lock
  // file isn't a normal file, crash_sender will never work correctly.
  if (!SetUpLockFile()) {
    LOG(ERROR) << "Couldn't set up lock file";
    return false;
  }

  // Set up all the common crash state directories first.  If we can't guarantee
  // these basic paths, just give up & don't turn on anything else.
  if (!CrashCollector::InitializeSystemCrashDirectories(early)) {
    return false;
  }

  // Set up metrics flag directory. Returns with non-zero if we cannot create
  // it.
  if (!CrashCollector::InitializeSystemMetricsDirectories()) {
    return false;
  }

  return user_collector->Enable(early);
}

int BootCollect(bool always_allow_feedback,
                KernelCollector* kernel_collector,
                ECCollector* ec_collector,
                BERTCollector* bert_collector,
                UncleanShutdownCollector* unclean_shutdown_collector,
                EphemeralCrashCollector* ephemeral_crash_collector) {
  bool was_kernel_crash = false;
  bool was_unclean_shutdown = false;
  LOG(INFO) << "Running boot collector";

  if (always_allow_feedback || util::IsFeedbackAllowed(&s_metrics_lib)) {
    /* TODO(drinkcat): Distinguish between EC crash and unclean shutdown. */
    ec_collector->Collect();

    // Invoke to collect firmware bert dump.
    bert_collector->Collect();

    kernel_collector->Enable();
    if (kernel_collector->is_enabled()) {
      was_kernel_crash = kernel_collector->Collect();
    }
    was_unclean_shutdown = unclean_shutdown_collector->Collect();

    // Touch a file to notify the metrics daemon that a kernel
    // crash has been detected so that it can log the time since
    // the last kernel crash.
    if (was_kernel_crash) {
      TouchFile(FilePath(kKernelCrashDetected));
    } else if (was_unclean_shutdown) {
      // We only count an unclean shutdown if it did not come with
      // an associated kernel crash.
      TouchFile(FilePath(kUncleanShutdownDetected));
    }
    ephemeral_crash_collector->Collect();
  } else if (ephemeral_crash_collector->SkipConsent()) {
    ephemeral_crash_collector->Collect();
  }

  // The below calls happen independently of metrics consent, as they do not
  // generate any crash reports.

  // Must enable the unclean shutdown collector *after* collecting.
  unclean_shutdown_collector->Enable();

  // Copy lsb-release and os-release into system crash spool.  Done after
  // collecting so that boot-time collected crashes will be associated with the
  // previous boot.
  unclean_shutdown_collector->SaveVersionData();

  // Presence of this files unblocks powerd from performing lid-closed action
  // (crbug.com/988831).
  TouchFile(FilePath(kBootCollectorDone));

  return 0;
}

// Ensure stdout, stdin, and stderr are open file descriptors.  If
// they are not, any code which writes to stderr/stdout may write out
// to files opened during execution.  In particular, when
// crash_reporter is run by the kernel coredump pipe handler (via
// kthread_create/kernel_execve), it will not have file table entries
// 1 and 2 (stdout and stderr) populated.  We populate them here.
void OpenStandardFileDescriptors() {
  int new_fd = -1;
  // We open /dev/null to fill in any of the standard [0, 2] file
  // descriptors.  We leave these open for the duration of the
  // process.  This works because open returns the lowest numbered
  // invalid fd.
  do {
    new_fd = open("/dev/null", 0);
    CHECK_GE(new_fd, 0) << "Unable to open /dev/null";
  } while (new_fd >= 0 && new_fd <= 2);
  close(new_fd);
}

// Reduce privs that we don't need.  But we still need:
// - The top most /proc to pull details out of it.
// - Read access to the crashing process's memory (regardless of user).
// - Write access to the crash spool dir.
void EnterSandbox(bool write_proc, bool log_to_stderr) {
  // If we're not root, we won't be able to jail ourselves (well, we could if
  // we used user namespaces, but maybe later).  Need to double check handling
  // when called by chrome to process its crashes.
  if (getuid() != 0)
    return;

  struct minijail* j = minijail_new();
  minijail_namespace_ipc(j);
  minijail_namespace_uts(j);
  minijail_namespace_net(j);
  minijail_namespace_vfs(j);
  // Remount mounts as MS_SLAVE to prevent crash_reporter from holding on to
  // mounts that might be unmounted in the root mount namespace.
  minijail_remount_mode(j, MS_SLAVE);
  minijail_mount_tmp(j);
  minijail_mount_dev(j);
  if (!log_to_stderr)
    minijail_bind(j, "/dev/log", "/dev/log", 0);
  minijail_no_new_privs(j);
  minijail_new_session_keyring(j);

  // If we're initializing the system, we need to write to /proc/sys/.
  if (!write_proc) {
    minijail_remount_proc_readonly(j);
  }

  minijail_enter(j);
  minijail_destroy(j);
}

}  // namespace

// Information to invoke a specific call on a collector.
struct InvocationInfo {
  // True iff this callback should be invoked.
  // Once this is true and we invoke the associated callback, main() returns,
  // so only one handler can run for each execution of crash_reporter.
  bool should_handle;
  // Callback to invoke if |should_handle| is true. (can be null).
  base::RepeatingCallback<bool()> cb;
};

// Information required to initialize and invoke a collector
struct CollectorInfo {
  // An un-owned pointer to the collector
  CrashCollector* collector;
  // Initialization function. If none is specified, invoke the default
  // crash_collector Initialize().
  base::RepeatingClosure init;
  // List of handlers with associated conditions.
  // If a particular condition is true, run init and the associated handler (if
  // any). If there is no associated handler, keep going.
  std::vector<InvocationInfo> handlers;
};

int main(int argc, char* argv[]) {
  DEFINE_bool(init, false, "Initialize crash logging");
  DEFINE_bool(boot_collect, false, "Run per-boot crash collection tasks");
  DEFINE_bool(clean_shutdown, false, "Signal clean shutdown");
  DEFINE_bool(mount_failure, false, "Report mount failure");
  DEFINE_bool(umount_failure, false, "Report umount failure");
  DEFINE_string(mount_device, "",
                "Device that failed to mount. Used with --mount_failure and "
                "--umount_failure");
  DEFINE_bool(ephemeral_collect, false,
              "Move crash reports to more persistent storage if available "
              "(tmpfs -> reboot vault) or (tmpfs/reboot vault -> encstateful)");
  DEFINE_bool(crash_test, false, "Crash test");
  DEFINE_bool(early, false,
              "Modifies crash-reporter to work during early boot");
  DEFINE_bool(preserve_across_clobber, false,
              "Persist early user crash reports across clobbers.");
  DEFINE_string(user, "", "User crash info (pid:signal:exec_name)");
  DEFINE_string(udev, "", "Udev event description (type:device:subsystem)");
  DEFINE_bool(kernel_warning, false, "Report collected kernel warning");
  DEFINE_bool(kernel_iwlwifi_error, false,
              "Report collected kernel iwlwifi error");
  DEFINE_bool(kernel_wifi_warning, false,
              "Report collected kernel wifi warning");
  DEFINE_bool(kernel_smmu_fault, false, "Report collected kernel smmu faults");
  DEFINE_bool(kernel_suspend_warning, false,
              "Report collected kernel suspend warning");
  DEFINE_bool(missed_chrome_crash, false,
              "Report that we missed a Chrome crash");
  DEFINE_int32(recent_miss_count, -1,
               "For missed_chrome_crash, how many Chrome crashes have we "
               "missed over the last 1 minute");
  DEFINE_int32(recent_match_count, -1,
               "For missed_chrome_crash, how many Chrome crashes have we "
               "matched over the last 1 minute");
  DEFINE_int32(pending_miss_count, -1,
               "For missed_chrome_crash, how many Chrome crashes are we "
               "tracking that might be counted as a miss soon");
  DEFINE_bool(log_to_stderr, false, "Log to stderr instead of syslog.");
  DEFINE_string(arc_service_failure, "",
                "The specific ARC service name that failed");
  DEFINE_bool(suspend_failure, false, "Report collected suspend failure logs.");
  DEFINE_bool(vm_crash, false, "Report collected from VM crash");
  DEFINE_int32(vm_pid, -1, "PID of the main VM process");
  DEFINE_bool(crash_reporter_crashed, false,
              "Report crash_reporter itself crashing");
  DEFINE_string(service_failure, "", "The specific service name that failed");
  DEFINE_bool(selinux_violation, false, "Report collected SELinux violation");
  // TODO(crbug.com/1000398): Remove --chrome flag after Chrome switches from
  // breakpad to crashpad.
  // Note: --chrome is being replaced by --chrome_memfd;
  //       --chrome_dump_dir is only used for tests and only used when
  // --chrome_memfd is used and not when --chrome is used.
  DEFINE_string(chrome, "", "Chrome crash dump file");
  DEFINE_int32(chrome_memfd, -1, "Chrome crash dump memfd");
  DEFINE_string(chrome_dump_dir, "",
                "Directory to write Chrome minidumps, used for tests only");
  DEFINE_int32(pid, -1, "PID of crashing process");
  DEFINE_int32(uid, -1, "UID of crashing process");
  DEFINE_string(exe, "", "Executable name of crashing process");
  DEFINE_string(error_key, "",
                "Key for error reports. Replaces exe for some errors that "
                "aren't tied to an executable. Unlike exe, this is not "
                "uploaded as part of the crash report.");
  DEFINE_int64(crash_loop_before, -1,
               "UNIX timestamp. If invoked before this time, use the special "
               "login-crash-loop handling system. (Keep crash report in memory "
               "and then pass to debugd for immediate upload.)");
  DEFINE_bool(core2md_failure, false, "Core2md failure test");
  DEFINE_bool(directory_failure, false, "Spool directory failure test");
  DEFINE_bool(
      always_allow_feedback, false,
      "Force if feedback is allowed check to return true, used for tests only");
#if USE_CHEETS
  DEFINE_string(arc_java_crash, "",
                "Read Java crash log of the given type from standard input");
  DEFINE_string(arc_device, "", "Metadata for ARC crashes");
  DEFINE_string(arc_board, "", "Metadata for ARC crashes");
  DEFINE_string(arc_cpu_abi, "", "Metadata for ARC crashes");
  DEFINE_string(arc_fingerprint, "", "Metadata for ARC crashes");
  DEFINE_bool(arc_is_arcvm, false, "Is ARCVM");
  DEFINE_bool(arc_native, false, "ARC Native Crash");
  DEFINE_int64(arc_native_time, -1,
               "UNIX timestamp of the time when the native crash happened. "
               "Metadata for ARCVM native crashes");
  DEFINE_bool(arc_kernel, false, "ARC Kernel Crash");
#endif

  OpenStandardFileDescriptors();
  FilePath my_path = base::MakeAbsoluteFilePath(FilePath(argv[0]));
  brillo::FlagHelper::Init(argc, argv, "Chromium OS Crash Reporter");

  base::SingleThreadTaskExecutor task_executor(base::MessagePumpType::IO);
  base::FileDescriptorWatcher watcher(task_executor.task_runner());

  // In certain cases, /dev/log may not be available: log to stderr instead.
  if (FLAGS_log_to_stderr) {
    brillo::InitLog(brillo::kLogToStderr);
  } else {
    brillo::OpenLog(my_path.BaseName().value().c_str(), true);
    brillo::InitLog(brillo::kLogToSyslog);
  }

  if (util::SkipCrashCollection(argc, argv)) {
    return 0;
  }

  bool always_allow_feedback = false;
  if (FLAGS_always_allow_feedback) {
    CHECK(util::IsTestImage()) << "--always_allow_feedback is only for tests";
    LOG(INFO) << "--always_allow_feedback set; skipping consent check";
    always_allow_feedback = true;
  }

  // Make it possible to test what happens when we crash while handling a crash.
  if (FLAGS_crash_test) {
    LOG(ERROR) << "crash_test requested";
    *(volatile char*)0 = 0;
    return 0;
  }

  // Now that we've processed the command line, sandbox ourselves.
  EnterSandbox(FLAGS_init || FLAGS_clean_shutdown, FLAGS_log_to_stderr);

  // Decide if we should use Crash-Loop sending mode. If session_manager sees
  // several Chrome crashes in a brief period, it will log the user out. On the
  // last Chrome startup before it logs the user out, it will set the
  // --crash_loop_before flag. The value of the flag will be a time_t timestamp
  // giving the last second at which a crash would be considered a crash loop
  // and thus log the user out. If we have another crash before that second,
  // we have detected a crash-loop and we want to invoke special handling
  // (specifically, we don't want to save the crash in the user's home directory
  // because that will be inaccessible to crash_sender once the user is logged
  // out).
  CrashCollector::CrashSendingMode crash_sending_mode =
      CrashCollector::kNormalCrashSendMode;
  if (FLAGS_crash_loop_before >= 0) {
    base::Time crash_loop_before =
        base::Time::FromTimeT(static_cast<time_t>(FLAGS_crash_loop_before));
    if (base::Time::Now() <= crash_loop_before) {
      crash_sending_mode = CrashCollector::kCrashLoopSendingMode;
      LOG(INFO) << "Using crash loop sending mode";
    }
  }

  UserCollectorBase::CrashAttributes user_crash_attrs;
  if (!FLAGS_user.empty()) {
    base::Optional<UserCollectorBase::CrashAttributes> attrs =
        UserCollectorBase::ParseCrashAttributes(FLAGS_user);
    if (!attrs.has_value()) {
      LOG(ERROR) << "Invalid parameter: --user=" << FLAGS_user;
      return 1;
    }
    user_crash_attrs = *attrs;
  }

  std::vector<CollectorInfo> collectors;
#if USE_CHEETS
  ArcvmNativeCollector arcvm_native_collector;
  collectors.push_back({
      .collector = &arcvm_native_collector,
      .handlers = {{
          // This handles native crashes of ARCVM.
          .should_handle = FLAGS_arc_is_arcvm && FLAGS_arc_native,
          .cb = base::BindRepeating(
              &ArcvmNativeCollector::HandleCrash,
              base::Unretained(&arcvm_native_collector),
              arc_util::BuildProperty{.device = FLAGS_arc_device,
                                      .board = FLAGS_arc_board,
                                      .cpu_abi = FLAGS_arc_cpu_abi,
                                      .fingerprint = FLAGS_arc_fingerprint},
              ArcvmNativeCollector::CrashInfo{
                  .time = static_cast<time_t>(FLAGS_arc_native_time),
                  .pid = FLAGS_pid,
                  .exec_name = FLAGS_exe}),
      }},
  });

  ArcvmKernelCollector arcvm_kernel_collector;
  collectors.push_back({
      .collector = &arcvm_kernel_collector,
      .handlers = {{
          // This handles kernel crashes of ARCVM.
          .should_handle = FLAGS_arc_is_arcvm && FLAGS_arc_kernel,
          .cb = base::BindRepeating(&ArcvmKernelCollector::HandleCrash,
                                    base::Unretained(&arcvm_kernel_collector),
                                    arc_util::BuildProperty{
                                        .device = FLAGS_arc_device,
                                        .board = FLAGS_arc_board,
                                        .cpu_abi = FLAGS_arc_cpu_abi,
                                        .fingerprint = FLAGS_arc_fingerprint,
                                    }),
      }},
  });

  ArcCollector arc_collector;

  // Always initialize arc_collector so that we can use it to determine if the
  // process is an arc process.
  arc_collector.Initialize(FLAGS_directory_failure, false /* early */);
  bool is_arc_process = !FLAGS_user.empty() && ArcCollector::IsArcRunning() &&
                        arc_collector.IsArcProcess(user_crash_attrs.pid);

  collectors.push_back({
      .collector = &arc_collector,
      .init = base::DoNothing(),
      .handlers =
          {{
               // This handles native crashes of ARC++.
               .should_handle = !FLAGS_arc_is_arcvm && is_arc_process,
               .cb = base::BindRepeating(&ArcCollector::HandleCrash,
                                         base::Unretained(&arc_collector),
                                         user_crash_attrs, nullptr),
           },
           {
               // This handles Java app crashes of ARC++ and ARCVM.
               .should_handle = !FLAGS_arc_java_crash.empty(),
               .cb = base::BindRepeating(
                   &ArcCollector::HandleJavaCrash,
                   base::Unretained(&arc_collector), FLAGS_arc_java_crash,
                   arc_util::BuildProperty{
                       .device = FLAGS_arc_device,
                       .board = FLAGS_arc_board,
                       .cpu_abi = FLAGS_arc_cpu_abi,
                       .fingerprint = FLAGS_arc_fingerprint,
                   }),
           }},
  });
#else   // USE_CHEETS
  bool is_arc_process = false;
#endif  // USE_CHEETS

  UserCollector user_collector;
  collectors.push_back({
      .collector = &user_collector,
      .init = base::BindRepeating(&UserCollector::Initialize,
                                  base::Unretained(&user_collector),
                                  my_path.value(), FLAGS_core2md_failure,
                                  FLAGS_directory_failure, FLAGS_early),
      .handlers = {{
                       // NOTE: This is not handling a crash; it's instead
                       // initializing the entire crash reporting system.
                       // So, leave |cb| unset and call InitializeSystem
                       // manually below.
                       .should_handle = FLAGS_init,
                   },
                   {
                       .should_handle = FLAGS_clean_shutdown,
                       // Leave cb unset: clean_shutdown requires other
                       // collectors, so it's handled later.
                   },
                   {
                       .should_handle = !FLAGS_user.empty() && !is_arc_process,
                       .cb = base::BindRepeating(
                           &UserCollector::HandleCrash,
                           base::Unretained(&user_collector), user_crash_attrs,
                           nullptr),
                   }},
  });

  EphemeralCrashCollector ephemeral_crash_collector;
  collectors.push_back({
      .collector = &ephemeral_crash_collector,
      .init = base::BindRepeating(&EphemeralCrashCollector::Initialize,
                                  base::Unretained(&ephemeral_crash_collector),
                                  FLAGS_preserve_across_clobber),
      .handlers =
          {{
               .should_handle = FLAGS_ephemeral_collect,
               .cb = base::BindRepeating(
                   &EphemeralCrashCollector::Collect,
                   base::Unretained(&ephemeral_crash_collector)),
           },
           {
               .should_handle = FLAGS_boot_collect,
               // leave cb empty because boot_collect needs multiple collectors.
               // It's handled separately at the end of main.
           }},
  });

  MountFailureCollector mount_failure_collector(
      MountFailureCollector::ValidateStorageDeviceType(FLAGS_mount_device));
  collectors.push_back({
      .collector = &mount_failure_collector,
      .handlers = {{
          .should_handle = FLAGS_mount_failure || FLAGS_umount_failure,
          .cb = base::BindRepeating(&MountFailureCollector::Collect,
                                    base::Unretained(&mount_failure_collector),
                                    FLAGS_mount_failure),
      }},
  });

  MissedCrashCollector missed_crash_collector;
  collectors.push_back({
      .collector = &missed_crash_collector,
      .handlers = {{
          .should_handle = FLAGS_missed_chrome_crash,
          .cb = base::BindRepeating(&MissedCrashCollector::Collect,
                                    base::Unretained(&missed_crash_collector),
                                    FLAGS_pid, FLAGS_recent_miss_count,
                                    FLAGS_recent_match_count,
                                    FLAGS_pending_miss_count),
      }},
  });

  UncleanShutdownCollector unclean_shutdown_collector;
  collectors.push_back({
      .collector = &unclean_shutdown_collector,
      .handlers = {{
          .should_handle = FLAGS_boot_collect || FLAGS_clean_shutdown,
          // leave cb empty because both of these need multiple collectors and
          // are handled separately at the end of main.
      }},
  });

  std::vector<InvocationInfo> boot_handlers = {{
      .should_handle = FLAGS_boot_collect,
      // leave cb empty because boot_collect needs multiple collectors and is
      // handled separately at the end of main. should_handle is only true so
      // the collector gets initialized.
  }};

  KernelCollector kernel_collector;
  collectors.push_back({
      .collector = &kernel_collector,
      .handlers = boot_handlers,
  });

  ECCollector ec_collector;
  collectors.push_back({
      .collector = &ec_collector,
      .handlers = boot_handlers,
  });

  BERTCollector bert_collector;
  collectors.push_back({
      .collector = &bert_collector,
      .handlers = boot_handlers,
  });

  UdevCollector udev_collector;
  collectors.push_back({.collector = &udev_collector,
                        .handlers = {{
                            .should_handle = !FLAGS_udev.empty(),
                            .cb = base::BindRepeating(
                                &UdevCollector::HandleCrash,
                                base::Unretained(&udev_collector), FLAGS_udev),
                        }}});

  CHECK(FLAGS_chrome.empty() || FLAGS_chrome_memfd == -1)
      << "--chrome= and --chrome_memfd= cannot be both set";
  if (FLAGS_chrome_memfd == -1) {
    CHECK(FLAGS_error_key.empty())
        << "--error_key is only for --chrome_memfd crashes";
  }

  ChromeCollector chrome_collector(crash_sending_mode);
  collectors.push_back({
      .collector = &chrome_collector,
      .handlers = {{
                       .should_handle = !FLAGS_chrome.empty(),
                       .cb = base::BindRepeating(
                           &ChromeCollector::HandleCrash,
                           base::Unretained(&chrome_collector),
                           FilePath(FLAGS_chrome), FLAGS_pid, FLAGS_uid,
                           FLAGS_exe),
                   },
                   {
                       .should_handle = FLAGS_chrome_memfd >= 0,
                       .cb = base::BindRepeating(
                           &ChromeCollector::HandleCrashThroughMemfd,
                           base::Unretained(&chrome_collector),
                           FLAGS_chrome_memfd, FLAGS_pid, FLAGS_uid, FLAGS_exe,
                           FLAGS_error_key, FLAGS_chrome_dump_dir),
                   }},
  });

  KernelWarningCollector kernel_warning_collector;
  base::RepeatingCallback<bool(KernelWarningCollector::WarningType)>
      kernel_warn_cb =
          base::BindRepeating(&KernelWarningCollector::Collect,
                              base::Unretained(&kernel_warning_collector));
  collectors.push_back({
      .collector = &kernel_warning_collector,
      .handlers = {{
                       .should_handle = FLAGS_kernel_warning,
                       .cb = base::BindRepeating(
                           kernel_warn_cb,
                           KernelWarningCollector::WarningType::kGeneric),
                   },
                   {
                       .should_handle = FLAGS_kernel_wifi_warning,
                       .cb = base::BindRepeating(
                           kernel_warn_cb,
                           KernelWarningCollector::WarningType::kWifi),
                   },
                   {
                       .should_handle = FLAGS_kernel_smmu_fault,
                       .cb = base::BindRepeating(
                           kernel_warn_cb,
                           KernelWarningCollector::WarningType::kSMMUFault),
                   },
                   {
                       .should_handle = FLAGS_kernel_suspend_warning,
                       .cb = base::BindRepeating(
                           kernel_warn_cb,
                           KernelWarningCollector::WarningType::kSuspend),
                   },
                   {
                       .should_handle = FLAGS_kernel_iwlwifi_error,
                       .cb = base::BindRepeating(
                           kernel_warn_cb,
                           KernelWarningCollector::WarningType::kIwlwifi),
                   }},
  });

  GenericFailureCollector generic_failure_collector;
  collectors.push_back(
      {.collector = &generic_failure_collector,
       .handlers = {
           {
               .should_handle = FLAGS_suspend_failure,
               .cb = base::BindRepeating(
                   &GenericFailureCollector::Collect,
                   base::Unretained(&generic_failure_collector),
                   GenericFailureCollector::kSuspendFailure),
           },
           {
               .should_handle = !FLAGS_arc_service_failure.empty(),
               .cb = base::BindRepeating(
                   &GenericFailureCollector::CollectFull,
                   base::Unretained(&generic_failure_collector),
                   StringPrintf("%s-%s",
                                GenericFailureCollector::kArcServiceFailure,
                                FLAGS_arc_service_failure.c_str()),
                   GenericFailureCollector::kArcServiceFailure,
                   util::GetServiceFailureWeight()),
           },
           {
               .should_handle = !FLAGS_service_failure.empty(),
               .cb = base::BindRepeating(
                   &GenericFailureCollector::CollectFull,
                   base::Unretained(&generic_failure_collector),
                   StringPrintf("%s-%s",
                                GenericFailureCollector::kServiceFailure,
                                FLAGS_service_failure.c_str()),
                   GenericFailureCollector::kServiceFailure,
                   util::GetServiceFailureWeight()),
           }}});

  SELinuxViolationCollector selinux_violation_collector;
  collectors.push_back({.collector = &selinux_violation_collector,
                        .handlers = {{
                            .should_handle = FLAGS_selinux_violation,
                            .cb = base::BindRepeating(
                                &SELinuxViolationCollector::Collect,
                                base::Unretained(&selinux_violation_collector)),
                        }}});

  CrashReporterFailureCollector crash_reporter_failure_collector;
  collectors.push_back(
      {.collector = &crash_reporter_failure_collector,
       .handlers = {{
           .should_handle = FLAGS_crash_reporter_crashed,
           .cb = base::BindRepeating(
               &CrashReporterFailureCollector::Collect,
               base::Unretained(&crash_reporter_failure_collector)),
       }}});

  VmCollector vm_collector;
  collectors.push_back({.collector = &vm_collector,
                        .handlers = {{
                            .should_handle = FLAGS_vm_crash,
                            .cb = base::BindRepeating(
                                &VmCollector::Collect,
                                base::Unretained(&vm_collector), FLAGS_vm_pid),
                        }}});

  for (const CollectorInfo& collector : collectors) {
    bool ran_init = false;
    for (const InvocationInfo& info : collector.handlers) {
      if (info.should_handle) {
        if (!ran_init) {
          if (collector.init) {
            collector.init.Run();
          } else {
            collector.collector->Initialize(FLAGS_early);
          }
          ran_init = true;
        }
        if (info.cb) {
          // Accumulate logs to a string to help in diagnosing failures during
          // collection.
          brillo::LogToString(true);

          // Default to successful exit status if there's no consent.
          bool handled = true;
          // For early boot crash collectors, the consent file will not be
          // accessible.  Instead, check consent during boot collection.
          if (FLAGS_early || always_allow_feedback ||
              util::IsFeedbackAllowed(&s_metrics_lib)) {
            handled = info.cb.Run();
          } else if (collector.collector == &ephemeral_crash_collector &&
                     ephemeral_crash_collector.SkipConsent()) {
            // Due to the specific circumstances in which the ephemeral
            // collector runs, it might need to skip consent checks (e.g. if
            // it's running just after a disk clobber, the clobber may have
            // wiped out a user's preferences). Other collectors should not skip
            // consent checks.
            handled = info.cb.Run();
          }
          brillo::LogToString(false);
          return handled ? 0 : 1;
        }
      }
    }
  }

  if (FLAGS_init) {
    // Called manually to skip the normal consent checks; we always initialize
    // the system regardless of consent.
    return InitializeSystem(&user_collector, FLAGS_early) ? 0 : 1;
  }

  // These special cases (which use multiple collectors) are at the end so that
  // it's clear that all relevant collectors have been initialized.
  if (FLAGS_boot_collect) {
    return BootCollect(always_allow_feedback, &kernel_collector, &ec_collector,
                       &bert_collector, &unclean_shutdown_collector,
                       &ephemeral_crash_collector);
  }

  if (FLAGS_clean_shutdown) {
    int ret = 0;
    if (!unclean_shutdown_collector.Disable())
      ret = 1;
    if (!user_collector.Disable())
      ret = 1;
    return ret;
  }

  LOG(ERROR) << "Nothing to do! (Bad arguments?)";
  return 1;
}
