// Copyright 2018 The Crashpad Authors. All rights reserved.
//
// 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 "client/crash_report_database.h"

#include <stdint.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <utility>

#include "base/logging.h"
#include "base/macros.h"
#include "build/build_config.h"
#include "client/settings.h"
#include "util/file/directory_reader.h"
#include "util/file/filesystem.h"
#include "util/misc/initialization_state_dcheck.h"
#include "util/misc/memory_sanitizer.h"

namespace crashpad {

namespace {

base::FilePath ReplaceFinalExtension(
    const base::FilePath& path,
    const base::FilePath::StringType extension) {
  return base::FilePath(path.RemoveFinalExtension().value() + extension);
}

UUID UUIDFromReportPath(const base::FilePath& path) {
  UUID uuid;
  uuid.InitializeFromString(path.RemoveFinalExtension().BaseName().value());
  return uuid;
}

bool AttachmentNameIsOK(const std::string& name) {
  for (const char c : name) {
    if (c != '_' && c != '-' && c != '.' && !isalnum(c))
      return false;
  }
  return true;
}

using OperationStatus = CrashReportDatabase::OperationStatus;

constexpr base::FilePath::CharType kSettings[] =
    FILE_PATH_LITERAL("settings.dat");

constexpr base::FilePath::CharType kCrashReportExtension[] =
    FILE_PATH_LITERAL(".dmp");
constexpr base::FilePath::CharType kMetadataExtension[] =
    FILE_PATH_LITERAL(".meta");
constexpr base::FilePath::CharType kLockExtension[] =
    FILE_PATH_LITERAL(".lock");

constexpr base::FilePath::CharType kNewDirectory[] = FILE_PATH_LITERAL("new");
constexpr base::FilePath::CharType kPendingDirectory[] =
    FILE_PATH_LITERAL("pending");
constexpr base::FilePath::CharType kCompletedDirectory[] =
    FILE_PATH_LITERAL("completed");
constexpr base::FilePath::CharType kAttachmentsDirectory[] =
    FILE_PATH_LITERAL("attachments");

constexpr const base::FilePath::CharType* kReportDirectories[] = {
    kNewDirectory,
    kPendingDirectory,
    kCompletedDirectory,
};

enum {
  //! \brief Corresponds to uploaded bit of the report state.
  kAttributeUploaded = 1 << 0,

  //! \brief Corresponds to upload_explicity_requested bit of the report state.
  kAttributeUploadExplicitlyRequested = 1 << 1,
};

struct ReportMetadata {
  static constexpr int32_t kVersion = 1;

  int32_t version = kVersion;
  int32_t upload_attempts = 0;
  int64_t last_upload_attempt_time = 0;
  time_t creation_time = 0;
  uint8_t attributes = 0;
};

// A lock held while using database resources.
class ScopedLockFile {
 public:
  ScopedLockFile() = default;

  ScopedLockFile(const ScopedLockFile&) = delete;
  ScopedLockFile& operator=(const ScopedLockFile&) = delete;

  ~ScopedLockFile() = default;

  ScopedLockFile& operator=(ScopedLockFile&& other) {
    lock_file_.reset(other.lock_file_.release());
    return *this;
  }

  // Attempt to acquire a lock for the report at report_path.
  // Return `true` on success, otherwise `false`.
  bool ResetAcquire(const base::FilePath& report_path) {
    lock_file_.reset();

    base::FilePath lock_path(report_path.RemoveFinalExtension().value() +
                             kLockExtension);
    ScopedFileHandle lock_fd(LoggingOpenFileForWrite(
        lock_path, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly));
    if (!lock_fd.is_valid()) {
      return false;
    }
    lock_file_.reset(lock_path);

    time_t timestamp = time(nullptr);
    if (!LoggingWriteFile(lock_fd.get(), &timestamp, sizeof(timestamp))) {
      return false;
    }

    return true;
  }

  // Returns `true` if the lock is held.
  bool is_valid() const { return lock_file_.is_valid(); }

  // Returns `true` if the lockfile at lock_path has expired.
  static bool IsExpired(const base::FilePath& lock_path, time_t lockfile_ttl) {
    time_t now = time(nullptr);

    timespec filetime;
    if (FileModificationTime(lock_path, &filetime) &&
        filetime.tv_sec > now + lockfile_ttl) {
      return false;
    }

    ScopedFileHandle lock_fd(LoggingOpenFileForReadAndWrite(
        lock_path, FileWriteMode::kReuseOrFail, FilePermissions::kOwnerOnly));
    if (!lock_fd.is_valid()) {
      return false;
    }

    time_t timestamp;
    if (!LoggingReadFileExactly(lock_fd.get(), &timestamp, sizeof(timestamp))) {
      return false;
    }

    return now >= timestamp + lockfile_ttl;
  }

 private:
  ScopedRemoveFile lock_file_;
};

off_t GetFileSize(const base::FilePath& filepath) {
  struct stat statbuf;
  if (stat(filepath.value().c_str(), &statbuf) == 0) {
    return statbuf.st_size;
  }
  PLOG(ERROR) << "stat " << filepath.value();
  return 0;
}

void AddAttachmentSize(const base::FilePath& attachments_dir, uint64_t* size) {
  // Early return if the attachment directory does not exist.
  if (!IsDirectory(attachments_dir, /*allow_symlinks=*/false)) {
    return;
  }
  DirectoryReader reader;
  if (!reader.Open(attachments_dir)) {
    return;
  }
  base::FilePath attachment_filename;
  DirectoryReader::Result result;
  while ((result = reader.NextFile(&attachment_filename)) ==
         DirectoryReader::Result::kSuccess) {
    const base::FilePath attachment_filepath(
        attachments_dir.Append(attachment_filename));
    *size += GetFileSize(attachment_filepath);
  }
}

}  // namespace

class CrashReportDatabaseGeneric : public CrashReportDatabase {
 public:
  CrashReportDatabaseGeneric();

  CrashReportDatabaseGeneric(const CrashReportDatabaseGeneric&) = delete;
  CrashReportDatabaseGeneric& operator=(const CrashReportDatabaseGeneric&) =
      delete;

  ~CrashReportDatabaseGeneric() override;

  bool Initialize(const base::FilePath& path, bool may_create);

  // CrashReportDatabase:
  Settings* GetSettings() override;
  OperationStatus PrepareNewCrashReport(
      std::unique_ptr<NewReport>* report) override;
  OperationStatus FinishedWritingCrashReport(std::unique_ptr<NewReport> report,
                                             UUID* uuid) override;
  OperationStatus LookUpCrashReport(const UUID& uuid, Report* report) override;
  OperationStatus GetPendingReports(std::vector<Report>* reports) override;
  OperationStatus GetCompletedReports(std::vector<Report>* reports) override;
  OperationStatus GetReportForUploading(
      const UUID& uuid,
      std::unique_ptr<const UploadReport>* report,
      bool report_metrics) override;
  OperationStatus SkipReportUpload(const UUID& uuid,
                                   Metrics::CrashSkippedReason reason) override;
  OperationStatus DeleteReport(const UUID& uuid) override;
  OperationStatus RequestUpload(const UUID& uuid) override;
  int CleanDatabase(time_t lockfile_ttl) override;

  // Build a filepath for the directory for the report to hold attachments.
  base::FilePath AttachmentsPath(const UUID& uuid);

 private:
  struct LockfileUploadReport : public UploadReport {
    ScopedLockFile lock_file;
  };

  enum ReportState : int32_t {
    kUninitialized = -1,

    // Being created by a caller of PrepareNewCrashReport().
    kNew,

    // Created by FinishedWritingCrashReport(), but not yet uploaded.
    kPending,

    // Upload completed or skipped.
    kCompleted,

    // Specifies either kPending or kCompleted.
    kSearchable,
  };

  // CrashReportDatabase:
  OperationStatus RecordUploadAttempt(UploadReport* report,
                                      bool successful,
                                      const std::string& id) override;

  // Builds a filepath for the report with the specified uuid and state.
  base::FilePath ReportPath(const UUID& uuid, ReportState state);

  // Locates the report with id uuid and returns its file path in path and a
  // lock for the report in lock_file. This method succeeds as long as the
  // report file exists and the lock can be acquired. No validation is done on
  // the existence or content of the metadata file.
  OperationStatus LocateAndLockReport(const UUID& uuid,
                                      ReportState state,
                                      base::FilePath* path,
                                      ScopedLockFile* lock_file);

  // Locates, locks, and reads the metadata for the report with the specified
  // uuid and state. This method will fail and may remove reports if invalid
  // metadata is detected. state may be kPending, kCompleted, or kSearchable.
  OperationStatus CheckoutReport(const UUID& uuid,
                                 ReportState state,
                                 base::FilePath* path,
                                 ScopedLockFile* lock_file,
                                 Report* report);

  // Reads metadata for all reports in state and returns it in reports.
  OperationStatus ReportsInState(ReportState state,
                                 std::vector<Report>* reports);

  // Cleans lone metadata, reports, or expired locks in a particular state.
  int CleanReportsInState(ReportState state, time_t lockfile_ttl);

  // Cleans any attachments that have no associated report in any state.
  void CleanOrphanedAttachments();

  // Attempt to remove any attachments associated with the given report UUID.
  // There may not be any, so failing is not an error.
  void RemoveAttachmentsByUUID(const UUID& uuid);

  // Reads the metadata for a report from path and returns it in report.
  bool ReadMetadata(const base::FilePath& path, Report* report);

  // Wraps ReadMetadata and removes the report from the database on failure.
  bool CleaningReadMetadata(const base::FilePath& path, Report* report);

  // Writes metadata for a new report to the filesystem at path.
  static bool WriteNewMetadata(const base::FilePath& path);

  // Writes the metadata for report to the filesystem at path.
  static bool WriteMetadata(const base::FilePath& path, const Report& report);

  base::FilePath base_dir_;
  Settings settings_;
  InitializationStateDcheck initialized_;
};

FileWriter* CrashReportDatabase::NewReport::AddAttachment(
    const std::string& name) {
  if (!AttachmentNameIsOK(name)) {
    LOG(ERROR) << "invalid name for attachment " << name;
    return nullptr;
  }

  base::FilePath attachments_dir =
      static_cast<CrashReportDatabaseGeneric*>(database_)->AttachmentsPath(
          uuid_);
  if (!LoggingCreateDirectory(
          attachments_dir, FilePermissions::kOwnerOnly, true)) {
    return nullptr;
  }

  base::FilePath path = attachments_dir.Append(name);

  auto writer = std::make_unique<FileWriter>();
  if (!writer->Open(
          path, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly)) {
    LOG(ERROR) << "could not open " << path.value();
    return nullptr;
  }
  attachment_writers_.emplace_back(std::move(writer));
  attachment_removers_.emplace_back(ScopedRemoveFile(path));
  return attachment_writers_.back().get();
}

void CrashReportDatabase::UploadReport::InitializeAttachments() {
  base::FilePath attachments_dir =
      static_cast<CrashReportDatabaseGeneric*>(database_)->AttachmentsPath(
          uuid);
  if (!IsDirectory(attachments_dir, /*allow_symlinks=*/false)) {
    return;
  }
  DirectoryReader directory_reader;
  if (!directory_reader.Open(attachments_dir)) {
    return;
  }

  base::FilePath filename;
  DirectoryReader::Result dir_result;
  while ((dir_result = directory_reader.NextFile(&filename)) ==
         DirectoryReader::Result::kSuccess) {
    const base::FilePath filepath(attachments_dir.Append(filename));
    std::unique_ptr<FileReader> file_reader(std::make_unique<FileReader>());
    if (!file_reader->Open(filepath)) {
      LOG(ERROR) << "attachment " << filepath.value()
                 << " couldn't be opened, skipping";
      continue;
    }
    attachment_readers_.emplace_back(std::move(file_reader));
    attachment_map_[filename.value()] = attachment_readers_.back().get();
  }
}

CrashReportDatabaseGeneric::CrashReportDatabaseGeneric() = default;

CrashReportDatabaseGeneric::~CrashReportDatabaseGeneric() = default;

bool CrashReportDatabaseGeneric::Initialize(const base::FilePath& path,
                                            bool may_create) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
  base_dir_ = path;

  if (!IsDirectory(base_dir_, true) &&
      !(may_create &&
        LoggingCreateDirectory(base_dir_, FilePermissions::kOwnerOnly, true))) {
    return false;
  }

  for (const base::FilePath::CharType* subdir : kReportDirectories) {
    if (!LoggingCreateDirectory(
            base_dir_.Append(subdir), FilePermissions::kOwnerOnly, true)) {
      return false;
    }
  }

  if (!LoggingCreateDirectory(base_dir_.Append(kAttachmentsDirectory),
                              FilePermissions::kOwnerOnly,
                              true)) {
    return false;
  }

  if (!settings_.Initialize(base_dir_.Append(kSettings))) {
    return false;
  }

  INITIALIZATION_STATE_SET_VALID(initialized_);
  return true;
}

// static
std::unique_ptr<CrashReportDatabase> CrashReportDatabase::Initialize(
    const base::FilePath& path) {
  auto database = std::make_unique<CrashReportDatabaseGeneric>();
  return database->Initialize(path, true) ? std::move(database) : nullptr;
}

// static
std::unique_ptr<CrashReportDatabase>
CrashReportDatabase::InitializeWithoutCreating(const base::FilePath& path) {
  auto database = std::make_unique<CrashReportDatabaseGeneric>();
  return database->Initialize(path, false) ? std::move(database) : nullptr;
}

Settings* CrashReportDatabaseGeneric::GetSettings() {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return &settings_;
}

OperationStatus CrashReportDatabaseGeneric::PrepareNewCrashReport(
    std::unique_ptr<NewReport>* report) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  auto new_report = std::make_unique<NewReport>();
  if (!new_report->Initialize(
          this, base_dir_.Append(kNewDirectory), kCrashReportExtension)) {
    return kFileSystemError;
  }

  report->reset(new_report.release());
  return kNoError;
}

OperationStatus CrashReportDatabaseGeneric::FinishedWritingCrashReport(
    std::unique_ptr<NewReport> report,
    UUID* uuid) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  base::FilePath path = ReportPath(report->ReportID(), kPending);
  ScopedLockFile lock_file;
  if (!lock_file.ResetAcquire(path)) {
    return kBusyError;
  }

  if (!WriteNewMetadata(ReplaceFinalExtension(path, kMetadataExtension))) {
    return kDatabaseError;
  }

  FileOffset size = report->Writer()->Seek(0, SEEK_END);

  report->Writer()->Close();
  if (!MoveFileOrDirectory(report->file_remover_.get(), path)) {
    return kFileSystemError;
  }
  // We've moved the report to pending, so it no longer needs to be removed.
  ignore_result(report->file_remover_.release());

  // Close all the attachments and disarm their removers too.
  for (auto& writer : report->attachment_writers_) {
    writer->Close();
  }
  for (auto& remover : report->attachment_removers_) {
    ignore_result(remover.release());
  }

  *uuid = report->ReportID();

  Metrics::CrashReportPending(Metrics::PendingReportReason::kNewlyCreated);
  Metrics::CrashReportSize(size);

  return kNoError;
}

OperationStatus CrashReportDatabaseGeneric::LookUpCrashReport(const UUID& uuid,
                                                              Report* report) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  ScopedLockFile lock_file;
  base::FilePath path;
  return CheckoutReport(uuid, kSearchable, &path, &lock_file, report);
}

OperationStatus CrashReportDatabaseGeneric::GetPendingReports(
    std::vector<Report>* reports) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return ReportsInState(kPending, reports);
}

OperationStatus CrashReportDatabaseGeneric::GetCompletedReports(
    std::vector<Report>* reports) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return ReportsInState(kCompleted, reports);
}

OperationStatus CrashReportDatabaseGeneric::GetReportForUploading(
    const UUID& uuid,
    std::unique_ptr<const UploadReport>* report,
    bool report_metrics) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  auto upload_report = std::make_unique<LockfileUploadReport>();

  base::FilePath path;
  OperationStatus os = CheckoutReport(
      uuid, kPending, &path, &upload_report->lock_file, upload_report.get());
  if (os != kNoError) {
    return os;
  }

  if (!upload_report->Initialize(path, this)) {
    return kFileSystemError;
  }
  upload_report->report_metrics_ = report_metrics;

  report->reset(upload_report.release());
  return kNoError;
}

OperationStatus CrashReportDatabaseGeneric::SkipReportUpload(
    const UUID& uuid,
    Metrics::CrashSkippedReason reason) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  Metrics::CrashUploadSkipped(reason);

  base::FilePath path;
  ScopedLockFile lock_file;
  Report report;
  OperationStatus os =
      CheckoutReport(uuid, kPending, &path, &lock_file, &report);
  if (os != kNoError) {
    return os;
  }

  base::FilePath completed_path(ReportPath(uuid, kCompleted));
  ScopedLockFile completed_lock_file;
  if (!completed_lock_file.ResetAcquire(completed_path)) {
    return kBusyError;
  }

  report.upload_explicitly_requested = false;
  if (!WriteMetadata(completed_path, report)) {
    return kDatabaseError;
  }

  if (!MoveFileOrDirectory(path, completed_path)) {
    return kFileSystemError;
  }

  if (!LoggingRemoveFile(ReplaceFinalExtension(path, kMetadataExtension))) {
    return kDatabaseError;
  }

  return kNoError;
}

OperationStatus CrashReportDatabaseGeneric::DeleteReport(const UUID& uuid) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  base::FilePath path;
  ScopedLockFile lock_file;
  OperationStatus os =
      LocateAndLockReport(uuid, kSearchable, &path, &lock_file);
  if (os != kNoError) {
    return os;
  }

  if (!LoggingRemoveFile(path)) {
    return kFileSystemError;
  }

  if (!LoggingRemoveFile(ReplaceFinalExtension(path, kMetadataExtension))) {
    return kDatabaseError;
  }

  RemoveAttachmentsByUUID(uuid);

  return kNoError;
}

OperationStatus CrashReportDatabaseGeneric::RequestUpload(const UUID& uuid) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  base::FilePath path;
  ScopedLockFile lock_file;
  Report report;
  OperationStatus os =
      CheckoutReport(uuid, kSearchable, &path, &lock_file, &report);
  if (os != kNoError) {
    return os;
  }

  if (report.uploaded) {
    return kCannotRequestUpload;
  }

  report.upload_explicitly_requested = true;
  base::FilePath pending_path = ReportPath(uuid, kPending);
  if (!MoveFileOrDirectory(path, pending_path)) {
    return kFileSystemError;
  }

  if (!WriteMetadata(pending_path, report)) {
    return kDatabaseError;
  }

  if (pending_path != path) {
    if (!LoggingRemoveFile(ReplaceFinalExtension(path, kMetadataExtension))) {
      return kDatabaseError;
    }
  }

  Metrics::CrashReportPending(Metrics::PendingReportReason::kUserInitiated);
  return kNoError;
}

int CrashReportDatabaseGeneric::CleanDatabase(time_t lockfile_ttl) {
  int removed = 0;
  time_t now = time(nullptr);

  DirectoryReader reader;
  const base::FilePath new_dir(base_dir_.Append(kNewDirectory));
  if (reader.Open(new_dir)) {
    base::FilePath filename;
    DirectoryReader::Result result;
    while ((result = reader.NextFile(&filename)) ==
           DirectoryReader::Result::kSuccess) {
      const base::FilePath filepath(new_dir.Append(filename));
      timespec filetime;
      if (!FileModificationTime(filepath, &filetime)) {
        continue;
      }
      if (filetime.tv_sec <= now - lockfile_ttl) {
        if (LoggingRemoveFile(filepath)) {
          ++removed;
        }
      }
    }
  }

  removed += CleanReportsInState(kPending, lockfile_ttl);
  removed += CleanReportsInState(kCompleted, lockfile_ttl);
  CleanOrphanedAttachments();
  return removed;
}

OperationStatus CrashReportDatabaseGeneric::RecordUploadAttempt(
    UploadReport* report,
    bool successful,
    const std::string& id) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  if (report->report_metrics_) {
    Metrics::CrashUploadAttempted(successful);
  }
  time_t now = time(nullptr);

  report->id = id;
  report->uploaded = successful;
  report->last_upload_attempt_time = now;
  ++report->upload_attempts;

  base::FilePath report_path(report->file_path);

  ScopedLockFile lock_file;
  if (successful) {
    report->upload_explicitly_requested = false;

    base::FilePath completed_report_path = ReportPath(report->uuid, kCompleted);

    if (!lock_file.ResetAcquire(completed_report_path)) {
      return kBusyError;
    }

    report->Reader()->Close();
    if (!MoveFileOrDirectory(report_path, completed_report_path)) {
      return kFileSystemError;
    }

    LoggingRemoveFile(ReplaceFinalExtension(report_path, kMetadataExtension));
    report_path = completed_report_path;
  }

  if (!WriteMetadata(report_path, *report)) {
    return kDatabaseError;
  }

  if (!settings_.SetLastUploadAttemptTime(now)) {
    return kDatabaseError;
  }

  return kNoError;
}

base::FilePath CrashReportDatabaseGeneric::ReportPath(const UUID& uuid,
                                                      ReportState state) {
  DCHECK_NE(state, kUninitialized);
  DCHECK_NE(state, kSearchable);

#if defined(OS_WIN)
  const std::wstring uuid_string = uuid.ToString16();
#else
  const std::string uuid_string = uuid.ToString();
#endif

  return base_dir_.Append(kReportDirectories[state])
      .Append(uuid_string + kCrashReportExtension);
}

base::FilePath CrashReportDatabaseGeneric::AttachmentsPath(const UUID& uuid) {
#if defined(OS_WIN)
  const std::wstring uuid_string = uuid.ToString16();
#else
  const std::string uuid_string = uuid.ToString();
#endif

  return base_dir_.Append(kAttachmentsDirectory).Append(uuid_string);
}

OperationStatus CrashReportDatabaseGeneric::LocateAndLockReport(
    const UUID& uuid,
    ReportState desired_state,
    base::FilePath* path,
    ScopedLockFile* lock_file) {
  std::vector<ReportState> searchable_states;
  if (desired_state == kSearchable) {
    searchable_states.push_back(kPending);
    searchable_states.push_back(kCompleted);
  } else {
    DCHECK(desired_state == kPending || desired_state == kCompleted);
    searchable_states.push_back(desired_state);
  }

  for (const ReportState state : searchable_states) {
    base::FilePath local_path(ReportPath(uuid, state));
    ScopedLockFile local_lock;
    if (!local_lock.ResetAcquire(local_path)) {
      return kBusyError;
    }

    if (!IsRegularFile(local_path)) {
      continue;
    }

    *path = local_path;
    *lock_file = std::move(local_lock);
    return kNoError;
  }

  return kReportNotFound;
}

OperationStatus CrashReportDatabaseGeneric::CheckoutReport(
    const UUID& uuid,
    ReportState state,
    base::FilePath* path,
    ScopedLockFile* lock_file,
    Report* report) {
  ScopedLockFile local_lock;
  base::FilePath local_path;
  OperationStatus os =
      LocateAndLockReport(uuid, state, &local_path, &local_lock);
  if (os != kNoError) {
    return os;
  }

  if (!CleaningReadMetadata(local_path, report)) {
    return kDatabaseError;
  }

  *path = local_path;
  *lock_file = std::move(local_lock);
  return kNoError;
}

OperationStatus CrashReportDatabaseGeneric::ReportsInState(
    ReportState state,
    std::vector<Report>* reports) {
  DCHECK(reports->empty());
  DCHECK_NE(state, kUninitialized);
  DCHECK_NE(state, kSearchable);
  DCHECK_NE(state, kNew);

  const base::FilePath dir_path(base_dir_.Append(kReportDirectories[state]));
  DirectoryReader reader;
  if (!reader.Open(dir_path)) {
    return kDatabaseError;
  }

  base::FilePath filename;
  DirectoryReader::Result result;
  while ((result = reader.NextFile(&filename)) ==
         DirectoryReader::Result::kSuccess) {
    const base::FilePath::StringType extension(filename.FinalExtension());
    if (extension.compare(kCrashReportExtension) != 0) {
      continue;
    }

    const base::FilePath filepath(dir_path.Append(filename));
    ScopedLockFile lock_file;
    if (!lock_file.ResetAcquire(filepath)) {
      continue;
    }

    Report report;
    if (!CleaningReadMetadata(filepath, &report)) {
      continue;
    }
    reports->push_back(report);
    reports->back().file_path = filepath;
  }
  return kNoError;
}

int CrashReportDatabaseGeneric::CleanReportsInState(ReportState state,
                                                    time_t lockfile_ttl) {
  const base::FilePath dir_path(base_dir_.Append(kReportDirectories[state]));
  DirectoryReader reader;
  if (!reader.Open(dir_path)) {
    return 0;
  }

  int removed = 0;
  base::FilePath filename;
  DirectoryReader::Result result;
  while ((result = reader.NextFile(&filename)) ==
         DirectoryReader::Result::kSuccess) {
    const base::FilePath::StringType extension(filename.FinalExtension());
    const base::FilePath filepath(dir_path.Append(filename));

    // Remove any report files without metadata.
    if (extension.compare(kCrashReportExtension) == 0) {
      const base::FilePath metadata_path(
          ReplaceFinalExtension(filepath, kMetadataExtension));
      ScopedLockFile report_lock;
      if (report_lock.ResetAcquire(filepath) && !IsRegularFile(metadata_path) &&
          LoggingRemoveFile(filepath)) {
        ++removed;
        RemoveAttachmentsByUUID(UUIDFromReportPath(filepath));
      }
      continue;
    }

    // Remove any metadata files without report files.
    if (extension.compare(kMetadataExtension) == 0) {
      const base::FilePath report_path(
          ReplaceFinalExtension(filepath, kCrashReportExtension));
      ScopedLockFile report_lock;
      if (report_lock.ResetAcquire(report_path) &&
          !IsRegularFile(report_path) && LoggingRemoveFile(filepath)) {
        ++removed;
        RemoveAttachmentsByUUID(UUIDFromReportPath(filepath));
      }
      continue;
    }

    // Remove any expired locks only if we can remove the report and metadata.
    if (extension.compare(kLockExtension) == 0 &&
        ScopedLockFile::IsExpired(filepath, lockfile_ttl)) {
      const base::FilePath no_ext(filepath.RemoveFinalExtension());
      const base::FilePath report_path(no_ext.value() + kCrashReportExtension);
      const base::FilePath metadata_path(no_ext.value() + kMetadataExtension);
      if ((IsRegularFile(report_path) && !LoggingRemoveFile(report_path)) ||
          (IsRegularFile(metadata_path) && !LoggingRemoveFile(metadata_path))) {
        continue;
      }

      if (LoggingRemoveFile(filepath)) {
        ++removed;
        RemoveAttachmentsByUUID(UUIDFromReportPath(filepath));
      }
      continue;
    }
  }

  return removed;
}

void CrashReportDatabaseGeneric::CleanOrphanedAttachments() {
  base::FilePath root_attachments_dir(base_dir_.Append(kAttachmentsDirectory));
  DirectoryReader reader;
  if (!reader.Open(root_attachments_dir)) {
    return;
  }

  base::FilePath filename;
  DirectoryReader::Result result;
  while ((result = reader.NextFile(&filename)) ==
         DirectoryReader::Result::kSuccess) {
    const base::FilePath path(root_attachments_dir.Append(filename));
    if (IsDirectory(path, false)) {
      UUID uuid;
      if (!uuid.InitializeFromString(filename.value())) {
        LOG(ERROR) << "unexpected attachment dir name " << filename.value();
        continue;
      }

      // Check to see if the report is being created in "new".
      base::FilePath new_dir_path =
          base_dir_.Append(kNewDirectory)
              .Append(uuid.ToString() + kCrashReportExtension);
      if (IsRegularFile(new_dir_path)) {
        continue;
      }

      // Check to see if the report is in "pending" or "completed".
      ScopedLockFile local_lock;
      base::FilePath local_path;
      OperationStatus os =
          LocateAndLockReport(uuid, kSearchable, &local_path, &local_lock);
      if (os != kReportNotFound) {
        continue;
      }

      // Couldn't find a report, assume these attachments are orphaned.
      RemoveAttachmentsByUUID(uuid);
    }
  }
}

void CrashReportDatabaseGeneric::RemoveAttachmentsByUUID(const UUID& uuid) {
  base::FilePath attachments_dir = AttachmentsPath(uuid);
  if (!IsDirectory(attachments_dir, /*allow_symlinks=*/false)) {
    return;
  }
  DirectoryReader reader;
  if (!reader.Open(attachments_dir)) {
    return;
  }

  base::FilePath filename;
  DirectoryReader::Result result;
  while ((result = reader.NextFile(&filename)) ==
         DirectoryReader::Result::kSuccess) {
    const base::FilePath filepath(attachments_dir.Append(filename));
    LoggingRemoveFile(filepath);
  }

  LoggingRemoveDirectory(attachments_dir);
}

bool CrashReportDatabaseGeneric::ReadMetadata(const base::FilePath& path,
                                              Report* report) {
  const base::FilePath metadata_path(
      ReplaceFinalExtension(path, kMetadataExtension));

  ScopedFileHandle handle(LoggingOpenFileForRead(metadata_path));
  if (!handle.is_valid()) {
    return false;
  }

  UUID uuid;
  if (!uuid.InitializeFromString(
          path.BaseName().RemoveFinalExtension().value())) {
    LOG(ERROR) << "Couldn't interpret report uuid";
    return false;
  }

  ReportMetadata metadata;
  if (!LoggingReadFileExactly(handle.get(), &metadata, sizeof(metadata))) {
    return false;
  }

  if (metadata.version != ReportMetadata::kVersion) {
    LOG(ERROR) << "metadata version mismatch";
    return false;
  }

  if (!LoggingReadToEOF(handle.get(), &report->id)) {
    return false;
  }

  // Seed the total size with the main report size and then add the sizes of any
  // potential attachments.
  uint64_t total_size = GetFileSize(path);
  AddAttachmentSize(AttachmentsPath(uuid), &total_size);

  report->uuid = uuid;
  report->upload_attempts = metadata.upload_attempts;
  report->last_upload_attempt_time = metadata.last_upload_attempt_time;
  report->creation_time = metadata.creation_time;
  report->uploaded = (metadata.attributes & kAttributeUploaded) != 0;
  report->upload_explicitly_requested =
      (metadata.attributes & kAttributeUploadExplicitlyRequested) != 0;
  report->file_path = path;
  report->total_size = total_size;
  return true;
}

bool CrashReportDatabaseGeneric::CleaningReadMetadata(
    const base::FilePath& path,
    Report* report) {
  if (ReadMetadata(path, report)) {
    return true;
  }

  LoggingRemoveFile(path);
  LoggingRemoveFile(ReplaceFinalExtension(path, kMetadataExtension));
  RemoveAttachmentsByUUID(report->uuid);
  return false;
}

// static
bool CrashReportDatabaseGeneric::WriteNewMetadata(const base::FilePath& path) {
  const base::FilePath metadata_path(
      ReplaceFinalExtension(path, kMetadataExtension));

  ScopedFileHandle handle(LoggingOpenFileForWrite(metadata_path,
                                                  FileWriteMode::kCreateOrFail,
                                                  FilePermissions::kOwnerOnly));
  if (!handle.is_valid()) {
    return false;
  }

  ReportMetadata metadata;
#if defined(MEMORY_SANITIZER)
  // memset() + re-initialization is required to zero padding bytes for MSan.
  memset(&metadata, 0, sizeof(metadata));
#endif  // defined(MEMORY_SANITIZER)
  metadata = {};
  metadata.creation_time = time(nullptr);

  return LoggingWriteFile(handle.get(), &metadata, sizeof(metadata));
}

// static
bool CrashReportDatabaseGeneric::WriteMetadata(const base::FilePath& path,
                                               const Report& report) {
  const base::FilePath metadata_path(
      ReplaceFinalExtension(path, kMetadataExtension));

  ScopedFileHandle handle(
      LoggingOpenFileForWrite(metadata_path,
                              FileWriteMode::kTruncateOrCreate,
                              FilePermissions::kOwnerOnly));
  if (!handle.is_valid()) {
    return false;
  }

  ReportMetadata metadata;
#if defined(MEMORY_SANITIZER)
  // memset() + re-initialization is required to zero padding bytes for MSan.
  memset(&metadata, 0, sizeof(metadata));
#endif  // defined(MEMORY_SANITIZER)
  metadata = {};
  metadata.creation_time = report.creation_time;
  metadata.last_upload_attempt_time = report.last_upload_attempt_time;
  metadata.upload_attempts = report.upload_attempts;
  metadata.attributes =
      (report.uploaded ? kAttributeUploaded : 0) |
      (report.upload_explicitly_requested ? kAttributeUploadExplicitlyRequested
                                          : 0);

  return LoggingWriteFile(handle.get(), &metadata, sizeof(metadata)) &&
         LoggingWriteFile(handle.get(), report.id.c_str(), report.id.size());
}

}  // namespace crashpad
