// Copyright 2019 The Fuchsia 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 "src/developer/feedback/crash_reports/database.h"

#include <cstdint>
#include <memory>

#include "src/developer/feedback/crash_reports/constants.h"
#include "src/developer/feedback/crash_reports/report_util.h"
#include "src/lib/files/directory.h"
#include "src/lib/fxl/strings/string_printf.h"
#include "src/lib/syslog/cpp/logger.h"
#include "third_party/crashpad/client/prune_crash_reports.h"
#include "third_party/crashpad/util/misc/metrics.h"

namespace feedback {

using crashpad::FileReader;
using crashpad::UUID;

using CrashSkippedReason = crashpad::Metrics::CrashSkippedReason;
using OperationStatus = crashpad::CrashReportDatabase::OperationStatus;

constexpr char kCrashpadDatabasePath[] = "/tmp/crashes";
constexpr uint64_t kCrashpadDatabaseMaxSizeInKb = 5120u;

std::unique_ptr<Database> Database::TryCreate(std::shared_ptr<InfoContext> info_context,
                                              uint64_t max_crashpad_database_size_in_kb) {
  if (!files::IsDirectory(kCrashpadDatabasePath)) {
    files::CreateDirectory(kCrashpadDatabasePath);
  }

  auto crashpad_database =
      crashpad::CrashReportDatabase::Initialize(base::FilePath(kCrashpadDatabasePath));
  if (!crashpad_database) {
    FX_LOGS(ERROR) << fxl::StringPrintf("Error initializing local crash report database at %s",
                                        kCrashpadDatabasePath);
    info_context->Cobalt().LogOccurrence(cobalt::CrashpadFunctionError::kInitializeDatabase);
    return nullptr;
  }

  return std::unique_ptr<Database>(new Database(
      std::move(crashpad_database), max_crashpad_database_size_in_kb, std::move(info_context)));
}

Database::Database(std::unique_ptr<crashpad::CrashReportDatabase> database,
                   uint64_t max_crashpad_database_size_in_kb,
                   std::shared_ptr<InfoContext> info_context)
    : database_(std::move(database)),
      max_crashpad_database_size_in_kb_(max_crashpad_database_size_in_kb),
      info_(std::move(info_context)) {
  FX_CHECK(database_);
  info_.LogMaxCrashpadDatabaseSize(max_crashpad_database_size_in_kb_);
}

bool Database::MakeNewReport(const std::map<std::string, fuchsia::mem::Buffer>& attachments,
                             const std::optional<fuchsia::mem::Buffer>& minidump,
                             const std::map<std::string, std::string>& annotations,
                             crashpad::UUID* local_report_id) {
  // Create local Crashpad report.
  std::unique_ptr<crashpad::CrashReportDatabase::NewReport> report;
  if (const auto status = database_->PrepareNewCrashReport(&report);
      status != OperationStatus::kNoError) {
    info_.CrashpadError(cobalt::CrashpadFunctionError::kPrepareNewCrashReport);
    FX_LOGS(ERROR) << fxl::StringPrintf("Error creating local Crashpad report (%u)", status);
    return false;
  }

  // Write attachments.
  for (const auto& [filename, content] : attachments) {
    AddAttachment(filename, content, report.get());
  }

  // Optionally write minidump.
  if (minidump.has_value()) {
    if (!WriteVMO(minidump.value(), report->Writer())) {
      FX_LOGS(WARNING) << "Error attaching minidump to Crashpad report";
    }
  }

  // Finish new local Crashpad report.
  if (const auto status = database_->FinishedWritingCrashReport(std::move(report), local_report_id);
      status != OperationStatus::kNoError) {
    info_.CrashpadError(cobalt::CrashpadFunctionError::kFinishedWritingCrashReport);
    FX_LOGS(ERROR) << fxl::StringPrintf("Error writing local Crashpad report (%u)", status);
    return false;
  }

  additional_data_[*local_report_id] = {minidump.has_value(), /*upload_attempts=*/0u, annotations};
  return true;
}

std::unique_ptr<UploadReport> Database::GetUploadReport(const UUID& local_report_id) {
  if (!Contains(local_report_id)) {
    FX_LOGS(ERROR) << fxl::StringPrintf("Error fetching additional data for local crash report %s",
                                        local_report_id.ToString().c_str());
    // The database no longer contains the report (it was most likely pruned).
    return nullptr;
  }

  auto upload_report = std::make_unique<const crashpad::CrashReportDatabase::UploadReport>();
  if (const auto status = database_->GetReportForUploading(local_report_id, &upload_report);
      status != OperationStatus::kNoError) {
    info_.CrashpadError(cobalt::CrashpadFunctionError::kGetReportForUploading);
    FX_LOGS(ERROR) << fxl::StringPrintf(
        "Error getting upload report for local id %s from the database (%u)",
        local_report_id.ToString().c_str(), status);
    return nullptr;
  }

  return std::make_unique<UploadReport>(std::move(upload_report),
                                        additional_data_.at(local_report_id).annotations,
                                        additional_data_.at(local_report_id).has_minidump);
}

void Database::IncrementUploadAttempt(const crashpad::UUID& local_report_id) {
  if (!Contains(local_report_id)) {
    return;
  }

  additional_data_.at(local_report_id).upload_attempts += 1;
  info_.RecordUploadAttemptNumber(local_report_id.ToString(),
                                  additional_data_.at(local_report_id).upload_attempts);
}

bool Database::MarkAsUploaded(std::unique_ptr<UploadReport> upload_report,
                              const std::string& server_report_id) {
  if (!upload_report) {
    FX_LOGS(ERROR) << "upload report is null";
    return false;
  }

  const UUID local_report_id = upload_report->GetUUID();

  info_.MarkReportAsUploaded(local_report_id.ToString(), server_report_id,
                             additional_data_.at(local_report_id).upload_attempts);

  // We need to clean up before finalizing the report in the crashpad database as the operation may
  // fail.
  CleanUp(local_report_id);

  if (const auto status =
          database_->RecordUploadComplete(upload_report->TransferUploadReport(), server_report_id);
      status != OperationStatus::kNoError) {
    info_.CrashpadError(cobalt::CrashpadFunctionError::kRecordUploadComplete);
    FX_LOGS(ERROR) << fxl::StringPrintf(
        "Unable to record local crash report %s as uploaded in the database (%u)",
        local_report_id.ToString().c_str(), status);
    return false;
  }

  return true;
}

bool Database::Archive(const crashpad::UUID& local_report_id) {
  if (!Contains(local_report_id)) {
    FX_LOGS(INFO) << fxl::StringPrintf("Unable to archive local crash report ID %s",
                                       local_report_id.ToString().c_str());
    return false;
  }

  FX_LOGS(INFO) << fxl::StringPrintf("Archiving local crash report, ID %s, under %s",
                                     local_report_id.ToString().c_str(), kCrashpadDatabasePath);
  info_.MarkReportAsArchived(local_report_id.ToString(),
                             additional_data_.at(local_report_id).upload_attempts);

  // We need to clean up before finalizing the report in the crashpad database as the operation may
  // fail.
  CleanUp(local_report_id);

  if (const auto status =
          database_->SkipReportUpload(local_report_id, CrashSkippedReason::kUploadFailed);
      status != OperationStatus::kNoError) {
    info_.CrashpadError(cobalt::CrashpadFunctionError::kSkipReportUpload);
    FX_LOGS(ERROR) << fxl::StringPrintf(
        "Unable to record local crash report %s as skipped in the database (%u)",
        local_report_id.ToString().c_str(), status);
    return false;
  }

  return true;
}

bool Database::Contains(const crashpad::UUID& local_report_id) {
  return additional_data_.find(local_report_id) != additional_data_.end();
}

void Database::CleanUp(const UUID& local_report_id) { additional_data_.erase(local_report_id); }

size_t Database::GarbageCollect() {
  // We need to create a new condition every time we prune as it internally maintains a cumulated
  // total size as it iterates over the reports in the database and we want to reset that cumulated
  // total size every time we prune.
  crashpad::DatabaseSizePruneCondition pruning_condition(max_crashpad_database_size_in_kb_);
  const size_t num_pruned = crashpad::PruneCrashReportDatabase(database_.get(), &pruning_condition);
  if (num_pruned > 0) {
    FX_LOGS(INFO) << fxl::StringPrintf("Pruned %lu crash report(s) from Crashpad database",
                                       num_pruned);
  }

  // We set the |lockfile_ttl| to one day to ensure that reports in new aren't removed until
  // a period of time has passed in which it is certain they are orphaned.
  const size_t num_cleaned = database_->CleanDatabase(/*lockfile_ttl=*/60 * 60 * 24);
  if (num_cleaned > 0) {
    FX_LOGS(INFO) << fxl::StringPrintf("Cleaned %lu crash report(s) from Crashpad database",
                                       num_cleaned);
  }

  if (num_cleaned + num_pruned > 0) {
    // We need to store the |UUID|s to be removed from |additional_data_| because erasing a
    // |UUID| within the loop will invalidate the generated iterator and cause a use-after-free bug.
    std::vector<UUID> clean_up;
    crashpad::CrashReportDatabase::Report report;
    for (const auto& [uuid, _] : additional_data_) {
      if (database_->LookUpCrashReport(uuid, &report) != OperationStatus::kNoError) {
        clean_up.push_back(uuid);
      }
    }

    for (const auto& uuid : clean_up) {
      info_.MarkReportAsGarbageCollected(uuid.ToString(),
                                         additional_data_.at(uuid).upload_attempts);
      CleanUp(uuid);
    }
  }

  info_.LogGarbageCollection(num_cleaned, num_pruned);
  return num_cleaned + num_pruned;
}

}  // namespace feedback
