// Copyright 2015 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 <errno.h>
#include <fcntl.h>
#import <Foundation/Foundation.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <uuid/uuid.h>

#include "base/cxx17_backports.h"
#include "base/logging.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/posix/eintr_wrapper.h"
#include "base/scoped_generic.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "client/settings.h"
#include "util/file/file_io.h"
#include "util/mac/xattr.h"
#include "util/misc/initialization_state_dcheck.h"
#include "util/misc/metrics.h"

namespace crashpad {

namespace {

constexpr char kWriteDirectory[] = "new";
constexpr char kUploadPendingDirectory[] = "pending";
constexpr char kCompletedDirectory[] = "completed";

constexpr char kSettings[] = "settings.dat";

constexpr const char* kReportDirectories[] = {
    kWriteDirectory,
    kUploadPendingDirectory,
    kCompletedDirectory,
};

constexpr char kCrashReportFileExtension[] = "dmp";

constexpr char kXattrUUID[] = "uuid";
constexpr char kXattrCollectorID[] = "id";
constexpr char kXattrCreationTime[] = "creation_time";
constexpr char kXattrIsUploaded[] = "uploaded";
constexpr char kXattrLastUploadTime[] = "last_upload_time";
constexpr char kXattrUploadAttemptCount[] = "upload_count";
constexpr char kXattrIsUploadExplicitlyRequested[] =
    "upload_explicitly_requested";

constexpr char kXattrDatabaseInitialized[] = "initialized";

// Ensures that the node at |path| is a directory. If the |path| refers to a
// file, rather than a directory, returns false. Otherwise, returns true,
// indicating that |path| already was a directory.
bool EnsureDirectoryExists(const base::FilePath& path) {
  struct stat st;
  if (stat(path.value().c_str(), &st) != 0) {
    PLOG(ERROR) << "stat " << path.value();
    return false;
  }
  if (!S_ISDIR(st.st_mode)) {
    LOG(ERROR) << "stat " << path.value() << ": not a directory";
    return false;
  }
  return true;
}

// Ensures that the node at |path| is a directory, and creates it if it does
// not exist. If the |path| refers to a file, rather than a directory, or the
// directory could not be created, returns false. Otherwise, returns true,
// indicating that |path| already was or now is a directory.
bool CreateOrEnsureDirectoryExists(const base::FilePath& path) {
  if (mkdir(path.value().c_str(), 0755) == 0) {
    return true;
  }
  if (errno != EEXIST) {
    PLOG(ERROR) << "mkdir " << path.value();
    return false;
  }
  return EnsureDirectoryExists(path);
}

// Creates a long database xattr name from the short constant name. These names
// have changed, and new_name determines whether the returned xattr name will be
// the old name or its new equivalent.
std::string XattrNameInternal(const base::StringPiece& name, bool new_name) {
  return base::StringPrintf(new_name ? "org.chromium.crashpad.database.%s"
                                     : "com.googlecode.crashpad.%s",
                            name.data());
}

}  // namespace

//! \brief A CrashReportDatabase that uses HFS+ extended attributes to store
//!     report metadata.
//!
//! The database maintains three directories of reports: `"new"` to hold crash
//! reports that are in the process of being written, `"completed"` to hold
//! reports that have been written and are awaiting upload, and `"uploaded"` to
//! hold reports successfully uploaded to a collection server. If the user has
//! opted out of report collection, reports will still be written and moved
//! to the completed directory, but they just will not be uploaded.
//!
//! The database stores its metadata in extended filesystem attributes. To
//! ensure safe access, the report file is locked using `O_EXLOCK` during all
//! extended attribute operations. The lock should be obtained using
//! ObtainReportLock().
class CrashReportDatabaseMac : public CrashReportDatabase {
 public:
  explicit CrashReportDatabaseMac(const base::FilePath& path);
  virtual ~CrashReportDatabaseMac();

  bool Initialize(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;

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

  //! \brief Report states for use with LocateCrashReport().
  //!
  //! ReportState may be considered to be a bitfield.
  enum ReportState : uint8_t {
    kReportStateWrite = 1 << 0,  // in kWriteDirectory
    kReportStatePending = 1 << 1,  // in kUploadPendingDirectory
    kReportStateCompleted = 1 << 2,  // in kCompletedDirectory
    kReportStateAny =
        kReportStateWrite | kReportStatePending | kReportStateCompleted,
  };

  //! \brief A private extension of the Report class that maintains bookkeeping
  //!    information of the database.
  struct UploadReportMac : public UploadReport {
    //! \brief Stores the flock of the file for the duration of
    //!     GetReportForUploading() and RecordUploadAttempt().
    base::ScopedFD lock_fd;
  };

  //! \brief Locates a crash report in the database by UUID.
  //!
  //! \param[in] uuid The UUID of the crash report to locate.
  //! \param[in] desired_state The state of the report to locate, composed of
  //!     ReportState values.
  //!
  //! \return The full path to the report file, or an empty path if it cannot be
  //!     found.
  base::FilePath LocateCrashReport(const UUID& uuid, uint8_t desired_state);

  //! \brief Obtains an exclusive advisory lock on a file.
  //!
  //! The flock is used to prevent cross-process concurrent metadata reads or
  //! writes. While xattrs do not observe the lock, if the lock-then-mutate
  //! protocol is observed by all clients of the database, it still enforces
  //! synchronization.
  //!
  //! This does not block, and so callers must ensure that the lock is valid
  //! after calling.
  //!
  //! \param[in] path The path of the file to lock.
  //!
  //! \return A scoped lock object. If the result is not valid, an error is
  //!     logged.
  static base::ScopedFD ObtainReportLock(const base::FilePath& path);

  //! \brief Reads all the database xattrs from a file into a Report. The file
  //!     must be locked with ObtainReportLock.
  //!
  //! \param[in] path The path of the report.
  //! \param[out] report The object into which data will be read.
  //!
  //! \return `true` if all the metadata was read successfully, `false`
  //!     otherwise.
  bool ReadReportMetadataLocked(const base::FilePath& path, Report* report);

  //! \brief Reads the metadata from all the reports in a database subdirectory.
  //!      Invalid reports are skipped.
  //!
  //! \param[in] path The database subdirectory path.
  //! \param[out] reports An empty vector of reports, which will be filled.
  //!
  //! \return The operation status code.
  OperationStatus ReportsInDirectory(const base::FilePath& path,
                                     std::vector<Report>* reports);

  //! \brief Creates a database xattr name from the short constant name.
  //!
  //! \param[in] name The short name of the extended attribute.
  //!
  //! \return The long name of the extended attribute.
  std::string XattrName(const base::StringPiece& name);

  //! \brief Marks a report with a given path as completed.
  //!
  //! Assumes that the report is locked.
  //!
  //! \param[in] report_path The path of the file to mark completed.
  //! \param[out] out_path The path of the new file. This parameter is optional.
  //!
  //! \return The operation status code.
  CrashReportDatabase::OperationStatus MarkReportCompletedLocked(
      const base::FilePath& report_path,
      base::FilePath* out_path);

  base::FilePath base_dir_;
  Settings settings_;
  bool xattr_new_names_;
  InitializationStateDcheck initialized_;

  DISALLOW_COPY_AND_ASSIGN(CrashReportDatabaseMac);
};

FileWriter* CrashReportDatabase::NewReport::AddAttachment(
    const std::string& name) {
  // Attachments aren't implemented in the Mac database yet.
  return nullptr;
}

void CrashReportDatabase::UploadReport::InitializeAttachments() {
  // Attachments aren't implemented in the Mac database yet.
}

CrashReportDatabaseMac::CrashReportDatabaseMac(const base::FilePath& path)
    : CrashReportDatabase(),
      base_dir_(path),
      settings_(),
      xattr_new_names_(false),
      initialized_() {
}

CrashReportDatabaseMac::~CrashReportDatabaseMac() {}

bool CrashReportDatabaseMac::Initialize(bool may_create) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);

  // Check if the database already exists.
  if (may_create) {
    if (!CreateOrEnsureDirectoryExists(base_dir_)) {
      return false;
    }
  } else if (!EnsureDirectoryExists(base_dir_)) {
    return false;
  }

  // Create the three processing directories for the database.
  for (size_t i = 0; i < base::size(kReportDirectories); ++i) {
    if (!CreateOrEnsureDirectoryExists(base_dir_.Append(kReportDirectories[i])))
      return false;
  }

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

  // Do an xattr operation as the last step, to ensure the filesystem has
  // support for them. This xattr also serves as a marker for whether the
  // database uses old or new xattr names.
  bool value;
  if (ReadXattrBool(base_dir_,
                    XattrNameInternal(kXattrDatabaseInitialized, true),
                    &value) == XattrStatus::kOK &&
      value) {
    xattr_new_names_ = true;
  } else if (ReadXattrBool(base_dir_,
                           XattrNameInternal(kXattrDatabaseInitialized, false),
                           &value) == XattrStatus::kOK &&
             value) {
    xattr_new_names_ = false;
  } else {
    xattr_new_names_ = true;
    if (!WriteXattrBool(base_dir_, XattrName(kXattrDatabaseInitialized), true))
      return false;
  }

  INITIALIZATION_STATE_SET_VALID(initialized_);
  return true;
}

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

CrashReportDatabase::OperationStatus
CrashReportDatabaseMac::PrepareNewCrashReport(
    std::unique_ptr<NewReport>* out_report) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  std::unique_ptr<NewReport> report(new NewReport());
  if (!report->Initialize(this,
                          base_dir_.Append(kWriteDirectory),
                          std::string(".") + kCrashReportFileExtension)) {
    return kFileSystemError;
  }

  // TODO(rsesek): Potentially use an fsetxattr() here instead.
  if (!WriteXattr(report->file_remover_.get(),
                  XattrName(kXattrUUID),
                  report->ReportID().ToString())) {
    return kDatabaseError;
  }

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

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

  const base::FilePath& path = report->file_remover_.get();

  // Get the report's UUID to return.
  std::string uuid_string;
  if (ReadXattr(path, XattrName(kXattrUUID), &uuid_string) !=
          XattrStatus::kOK ||
      !uuid->InitializeFromString(uuid_string)) {
    LOG(ERROR) << "Failed to read UUID for crash report " << path.value();
    return kDatabaseError;
  }

  if (*uuid != report->ReportID()) {
    LOG(ERROR) << "UUID mismatch for crash report " << path.value();
    return kDatabaseError;
  }

  // Record the creation time of this report.
  if (!WriteXattrTimeT(path, XattrName(kXattrCreationTime), time(nullptr))) {
    return kDatabaseError;
  }

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

  // Move the report to its new location for uploading.
  base::FilePath new_path =
      base_dir_.Append(kUploadPendingDirectory).Append(path.BaseName());
  if (rename(path.value().c_str(), new_path.value().c_str()) != 0) {
    PLOG(ERROR) << "rename " << path.value() << " to " << new_path.value();
    return kFileSystemError;
  }
  ignore_result(report->file_remover_.release());

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

  return kNoError;
}

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

  base::FilePath path = LocateCrashReport(uuid, kReportStateAny);
  if (path.empty())
    return kReportNotFound;

  base::ScopedFD lock(ObtainReportLock(path));
  if (!lock.is_valid())
    return kBusyError;

  *report = Report();
  report->file_path = path;
  if (!ReadReportMetadataLocked(path, report))
    return kDatabaseError;

  return kNoError;
}

CrashReportDatabase::OperationStatus
CrashReportDatabaseMac::GetPendingReports(
    std::vector<CrashReportDatabase::Report>* reports) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  return ReportsInDirectory(base_dir_.Append(kUploadPendingDirectory), reports);
}

CrashReportDatabase::OperationStatus
CrashReportDatabaseMac::GetCompletedReports(
    std::vector<CrashReportDatabase::Report>* reports) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  return ReportsInDirectory(base_dir_.Append(kCompletedDirectory), reports);
}

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

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

  upload_report->file_path = LocateCrashReport(uuid, kReportStatePending);
  if (upload_report->file_path.empty())
    return kReportNotFound;

  base::ScopedFD lock(ObtainReportLock(upload_report->file_path));
  if (!lock.is_valid())
    return kBusyError;

  if (!ReadReportMetadataLocked(upload_report->file_path, upload_report.get()))
    return kDatabaseError;

  if (!upload_report->reader_->Open(upload_report->file_path)) {
    return kFileSystemError;
  }

  upload_report->database_ = this;
  upload_report->lock_fd.reset(lock.release());
  upload_report->report_metrics_ = report_metrics;
  report->reset(upload_report.release());
  return kNoError;
}

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

  if (report->report_metrics_) {
    Metrics::CrashUploadAttempted(successful);
  }

  DCHECK(report);
  DCHECK(successful || id.empty());

  base::FilePath report_path =
      LocateCrashReport(report->uuid, kReportStatePending);
  if (report_path.empty())
    return kReportNotFound;

  if (successful) {
    CrashReportDatabase::OperationStatus os =
        MarkReportCompletedLocked(report_path, &report_path);
    if (os != kNoError)
      return os;
  }

  if (!WriteXattrBool(report_path, XattrName(kXattrIsUploaded), successful)) {
    return kDatabaseError;
  }
  if (!WriteXattr(report_path, XattrName(kXattrCollectorID), id)) {
    return kDatabaseError;
  }

  time_t now = time(nullptr);
  if (!WriteXattrTimeT(report_path, XattrName(kXattrLastUploadTime), now)) {
    return kDatabaseError;
  }

  int upload_attempts = 0;
  std::string name = XattrName(kXattrUploadAttemptCount);
  if (ReadXattrInt(report_path, name, &upload_attempts) ==
          XattrStatus::kOtherError) {
    return kDatabaseError;
  }
  if (!WriteXattrInt(report_path, name, ++upload_attempts)) {
    return kDatabaseError;
  }

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

  return kNoError;
}

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

  Metrics::CrashUploadSkipped(reason);

  base::FilePath report_path = LocateCrashReport(uuid, kReportStatePending);
  if (report_path.empty())
    return kReportNotFound;

  base::ScopedFD lock(ObtainReportLock(report_path));
  if (!lock.is_valid())
    return kBusyError;

  return MarkReportCompletedLocked(report_path, nullptr);
}

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

  base::FilePath report_path = LocateCrashReport(uuid, kReportStateAny);
  if (report_path.empty())
    return kReportNotFound;

  base::ScopedFD lock(ObtainReportLock(report_path));
  if (!lock.is_valid())
    return kBusyError;

  if (unlink(report_path.value().c_str()) != 0) {
    PLOG(ERROR) << "unlink " << report_path.value();
    return kFileSystemError;
  }

  return kNoError;
}

base::FilePath CrashReportDatabaseMac::LocateCrashReport(
    const UUID& uuid,
    uint8_t desired_state) {
  const std::string target_uuid = uuid.ToString();

  std::vector<std::string> report_directories;
  if (desired_state & kReportStateWrite) {
    report_directories.push_back(kWriteDirectory);
  }
  if (desired_state & kReportStatePending) {
    report_directories.push_back(kUploadPendingDirectory);
  }
  if (desired_state & kReportStateCompleted) {
    report_directories.push_back(kCompletedDirectory);
  }

  for (const std::string& report_directory : report_directories) {
    base::FilePath path =
        base_dir_.Append(report_directory)
                 .Append(target_uuid + "." + kCrashReportFileExtension);

    // Test if the path exists.
    struct stat st;
    if (lstat(path.value().c_str(), &st)) {
      continue;
    }

    // Check that the UUID of the report matches.
    std::string uuid_string;
    if (ReadXattr(path, XattrName(kXattrUUID),
                  &uuid_string) == XattrStatus::kOK &&
        uuid_string == target_uuid) {
      return path;
    }
  }

  return base::FilePath();
}

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

  base::FilePath report_path =
      LocateCrashReport(uuid, kReportStatePending | kReportStateCompleted);
  if (report_path.empty())
    return kReportNotFound;

  base::ScopedFD lock(ObtainReportLock(report_path));
  if (!lock.is_valid())
    return kBusyError;

  // If the crash report has already been uploaded, don't request new upload.
  bool uploaded = false;
  XattrStatus status =
      ReadXattrBool(report_path, XattrName(kXattrIsUploaded), &uploaded);
  if (status == XattrStatus::kOtherError)
    return kDatabaseError;
  if (uploaded)
    return kCannotRequestUpload;

  // Mark the crash report as having upload explicitly requested by the user,
  // and move it to the pending state.
  if (!WriteXattrBool(
          report_path, XattrName(kXattrIsUploadExplicitlyRequested), true)) {
    return kDatabaseError;
  }

  base::FilePath new_path =
      base_dir_.Append(kUploadPendingDirectory).Append(report_path.BaseName());
  if (rename(report_path.value().c_str(), new_path.value().c_str()) != 0) {
    PLOG(ERROR) << "rename " << report_path.value() << " to "
                << new_path.value();
    return kFileSystemError;
  }

  Metrics::CrashReportPending(Metrics::PendingReportReason::kUserInitiated);

  return kNoError;
}

// static
base::ScopedFD CrashReportDatabaseMac::ObtainReportLock(
    const base::FilePath& path) {
  int fd = HANDLE_EINTR(
      open(path.value().c_str(),
           O_RDONLY | O_NONBLOCK | O_EXLOCK | O_NOCTTY | O_CLOEXEC));
  PLOG_IF(ERROR, fd < 0) << "open lock " << path.value();
  return base::ScopedFD(fd);
}

bool CrashReportDatabaseMac::ReadReportMetadataLocked(
    const base::FilePath& path, Report* report) {
  std::string uuid_string;
  if (ReadXattr(path, XattrName(kXattrUUID),
                &uuid_string) != XattrStatus::kOK ||
      !report->uuid.InitializeFromString(uuid_string)) {
    return false;
  }

  if (ReadXattrTimeT(path, XattrName(kXattrCreationTime),
                     &report->creation_time) != XattrStatus::kOK) {
    return false;
  }

  report->id = std::string();
  if (ReadXattr(path, XattrName(kXattrCollectorID),
                &report->id) == XattrStatus::kOtherError) {
    return false;
  }

  report->uploaded = false;
  if (ReadXattrBool(path, XattrName(kXattrIsUploaded),
                    &report->uploaded) == XattrStatus::kOtherError) {
    return false;
  }

  report->last_upload_attempt_time = 0;
  if (ReadXattrTimeT(path, XattrName(kXattrLastUploadTime),
                     &report->last_upload_attempt_time) ==
          XattrStatus::kOtherError) {
    return false;
  }

  report->upload_attempts = 0;
  if (ReadXattrInt(path, XattrName(kXattrUploadAttemptCount),
                   &report->upload_attempts) == XattrStatus::kOtherError) {
    return false;
  }

  report->upload_explicitly_requested = false;
  if (ReadXattrBool(path,
                    XattrName(kXattrIsUploadExplicitlyRequested),
                    &report->upload_explicitly_requested) ==
      XattrStatus::kOtherError) {
    return false;
  }

  // There are no attachments on Mac so the total size is the main report size.
  struct stat statbuf;
  if (stat(path.value().c_str(), &statbuf) != 0) {
    PLOG(ERROR) << "stat " << path.value();
    return false;
  }
  report->total_size = statbuf.st_size;

  return true;
}

CrashReportDatabase::OperationStatus CrashReportDatabaseMac::ReportsInDirectory(
    const base::FilePath& path,
    std::vector<CrashReportDatabase::Report>* reports) {
  base::mac::ScopedNSAutoreleasePool pool;

  DCHECK(reports->empty());

  NSError* error = nil;
  NSArray* paths = [[NSFileManager defaultManager]
      contentsOfDirectoryAtPath:base::SysUTF8ToNSString(path.value())
                          error:&error];
  if (error) {
    LOG(ERROR) << "Failed to enumerate reports in directory " << path.value()
               << ": " << [[error description] UTF8String];
    return kFileSystemError;
  }

  reports->reserve([paths count]);
  for (NSString* entry in paths) {
    Report report;
    report.file_path = path.Append([entry fileSystemRepresentation]);
    base::ScopedFD lock(ObtainReportLock(report.file_path));
    if (!lock.is_valid())
      continue;

    if (!ReadReportMetadataLocked(report.file_path, &report)) {
      LOG(WARNING) << "Failed to read report metadata for "
                   << report.file_path.value();
      continue;
    }
    reports->push_back(report);
  }

  return kNoError;
}

std::string CrashReportDatabaseMac::XattrName(const base::StringPiece& name) {
  return XattrNameInternal(name, xattr_new_names_);
}

CrashReportDatabase::OperationStatus
CrashReportDatabaseMac::MarkReportCompletedLocked(
    const base::FilePath& report_path,
    base::FilePath* out_path) {
  if (RemoveXattr(report_path, XattrName(kXattrIsUploadExplicitlyRequested)) ==
      XattrStatus::kOtherError) {
    return kDatabaseError;
  }

  base::FilePath new_path =
      base_dir_.Append(kCompletedDirectory).Append(report_path.BaseName());
  if (rename(report_path.value().c_str(), new_path.value().c_str()) != 0) {
    PLOG(ERROR) << "rename " << report_path.value() << " to "
                << new_path.value();
    return kFileSystemError;
  }

  if (out_path)
    *out_path = new_path;
  return kNoError;
}

std::unique_ptr<CrashReportDatabase> InitializeInternal(
    const base::FilePath& path,
    bool may_create) {
  std::unique_ptr<CrashReportDatabaseMac> database_mac(
      new CrashReportDatabaseMac(path));
  if (!database_mac->Initialize(may_create))
    database_mac.reset();

  return std::unique_ptr<CrashReportDatabase>(database_mac.release());
}

// static
std::unique_ptr<CrashReportDatabase> CrashReportDatabase::Initialize(
    const base::FilePath& path) {
  return InitializeInternal(path, true);
}

// static
std::unique_ptr<CrashReportDatabase>
CrashReportDatabase::InitializeWithoutCreating(const base::FilePath& path) {
  return InitializeInternal(path, false);
}

}  // namespace crashpad
