// 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/logging.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/posix/eintr_wrapper.h"
#include "base/scoped_generic.h"
#include "base/stl_util.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
