// 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 "build/build_config.h"
#include "client/settings.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/file.h"
#include "test/filesystem.h"
#include "test/scoped_temp_dir.h"
#include "util/file/file_io.h"
#include "util/file/filesystem.h"

namespace crashpad {
namespace test {
namespace {

class CrashReportDatabaseTest : public testing::Test {
 public:
  CrashReportDatabaseTest() {}

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

 protected:
  // testing::Test:
  void SetUp() override {
    db_ = CrashReportDatabase::Initialize(path());
    ASSERT_TRUE(db_);
  }

  void ResetDatabase() { db_.reset(); }

  CrashReportDatabase* db() { return db_.get(); }
  base::FilePath path() const {
    return temp_dir_.path().Append(FILE_PATH_LITERAL("crashpad_test_database"));
  }

  void CreateCrashReport(CrashReportDatabase::Report* report) {
    std::unique_ptr<CrashReportDatabase::NewReport> new_report;
    ASSERT_EQ(db_->PrepareNewCrashReport(&new_report),
              CrashReportDatabase::kNoError);
    static constexpr char kTest[] = "test";
    ASSERT_TRUE(new_report->Writer()->Write(kTest, sizeof(kTest)));

    char contents[sizeof(kTest)];
    FileReaderInterface* reader = new_report->Reader();
    ASSERT_TRUE(reader->ReadExactly(contents, sizeof(contents)));
    EXPECT_EQ(memcmp(contents, kTest, sizeof(contents)), 0);
    EXPECT_EQ(reader->ReadExactly(contents, 1), 0);

    UUID uuid;
    EXPECT_EQ(db_->FinishedWritingCrashReport(std::move(new_report), &uuid),
              CrashReportDatabase::kNoError);

    EXPECT_EQ(db_->LookUpCrashReport(uuid, report),
              CrashReportDatabase::kNoError);
    ExpectPreparedCrashReport(*report);
  }

  void UploadReport(const UUID& uuid, bool successful, const std::string& id) {
    Settings* const settings = db_->GetSettings();
    ASSERT_TRUE(settings);
    time_t times[2];
    ASSERT_TRUE(settings->GetLastUploadAttemptTime(&times[0]));

    std::unique_ptr<const CrashReportDatabase::UploadReport> report;
    ASSERT_EQ(db_->GetReportForUploading(uuid, &report),
              CrashReportDatabase::kNoError);
    EXPECT_NE(report->uuid, UUID());
    EXPECT_FALSE(report->file_path.empty());
    EXPECT_TRUE(FileExists(report->file_path)) << report->file_path.value();
    EXPECT_GT(report->creation_time, 0);
    if (successful) {
      EXPECT_EQ(db_->RecordUploadComplete(std::move(report), id),
                CrashReportDatabase::kNoError);
    } else {
      report.reset();
    }

    ASSERT_TRUE(settings->GetLastUploadAttemptTime(&times[1]));
    EXPECT_NE(times[1], 0);
    EXPECT_GE(times[1], times[0]);
  }

  void ExpectPreparedCrashReport(const CrashReportDatabase::Report& report) {
    EXPECT_NE(report.uuid, UUID());
    EXPECT_FALSE(report.file_path.empty());
    EXPECT_TRUE(FileExists(report.file_path)) << report.file_path.value();
    EXPECT_TRUE(report.id.empty());
    EXPECT_GT(report.creation_time, 0);
    EXPECT_FALSE(report.uploaded);
    EXPECT_EQ(report.last_upload_attempt_time, 0);
    EXPECT_EQ(report.upload_attempts, 0);
    EXPECT_FALSE(report.upload_explicitly_requested);
    EXPECT_GE(report.total_size, 0u);
  }

  void RelocateDatabase() {
    ResetDatabase();
    temp_dir_.Rename();
    SetUp();
  }

  CrashReportDatabase::OperationStatus RequestUpload(const UUID& uuid) {
    CrashReportDatabase::OperationStatus os = db()->RequestUpload(uuid);

    CrashReportDatabase::Report report;
    EXPECT_EQ(db_->LookUpCrashReport(uuid, &report),
              CrashReportDatabase::kNoError);

    return os;
  }

 private:
  ScopedTempDir temp_dir_;
  std::unique_ptr<CrashReportDatabase> db_;
};

TEST_F(CrashReportDatabaseTest, Initialize) {
  // Initialize the database for the first time, creating it.
  ASSERT_TRUE(db());

  Settings* settings = db()->GetSettings();

  UUID client_ids[3];
  ASSERT_TRUE(settings->GetClientID(&client_ids[0]));
  EXPECT_NE(client_ids[0], UUID());

  time_t last_upload_attempt_time;
  ASSERT_TRUE(settings->GetLastUploadAttemptTime(&last_upload_attempt_time));
  EXPECT_EQ(last_upload_attempt_time, 0);

  // Close and reopen the database at the same path.
  ResetDatabase();
  EXPECT_FALSE(db());
  auto db = CrashReportDatabase::InitializeWithoutCreating(path());
  ASSERT_TRUE(db);

  settings = db->GetSettings();

  ASSERT_TRUE(settings->GetClientID(&client_ids[1]));
  EXPECT_EQ(client_ids[1], client_ids[0]);

  ASSERT_TRUE(settings->GetLastUploadAttemptTime(&last_upload_attempt_time));
  EXPECT_EQ(last_upload_attempt_time, 0);

  // Check that the database can also be opened by the method that is permitted
  // to create it.
  db = CrashReportDatabase::Initialize(path());
  ASSERT_TRUE(db);

  settings = db->GetSettings();

  ASSERT_TRUE(settings->GetClientID(&client_ids[2]));
  EXPECT_EQ(client_ids[2], client_ids[0]);

  ASSERT_TRUE(settings->GetLastUploadAttemptTime(&last_upload_attempt_time));
  EXPECT_EQ(last_upload_attempt_time, 0);

  std::vector<CrashReportDatabase::Report> reports;
  EXPECT_EQ(db->GetPendingReports(&reports), CrashReportDatabase::kNoError);
  EXPECT_TRUE(reports.empty());
  reports.clear();
  EXPECT_EQ(db->GetCompletedReports(&reports), CrashReportDatabase::kNoError);
  EXPECT_TRUE(reports.empty());

  // InitializeWithoutCreating() shouldn’t create a nonexistent database.
  base::FilePath non_database_path =
      path().DirName().Append(FILE_PATH_LITERAL("not_a_database"));
  db = CrashReportDatabase::InitializeWithoutCreating(non_database_path);
  EXPECT_FALSE(db);
}

TEST_F(CrashReportDatabaseTest, NewCrashReport) {
  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
  EXPECT_EQ(db()->PrepareNewCrashReport(&new_report),
            CrashReportDatabase::kNoError);
  UUID expect_uuid = new_report->ReportID();
  UUID uuid;
  EXPECT_EQ(db()->FinishedWritingCrashReport(std::move(new_report), &uuid),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(uuid, expect_uuid);

  CrashReportDatabase::Report report;
  EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
            CrashReportDatabase::kNoError);
  ExpectPreparedCrashReport(report);

  std::vector<CrashReportDatabase::Report> reports;
  EXPECT_EQ(db()->GetPendingReports(&reports), CrashReportDatabase::kNoError);
  ASSERT_EQ(reports.size(), 1u);
  EXPECT_EQ(reports[0].uuid, report.uuid);

  reports.clear();
  EXPECT_EQ(db()->GetCompletedReports(&reports), CrashReportDatabase::kNoError);
  EXPECT_TRUE(reports.empty());
}

TEST_F(CrashReportDatabaseTest, LookUpCrashReport) {
  UUID uuid;

  {
    CrashReportDatabase::Report report;
    CreateCrashReport(&report);
    uuid = report.uuid;
  }

  {
    CrashReportDatabase::Report report;
    EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
              CrashReportDatabase::kNoError);
    EXPECT_EQ(report.uuid, uuid);
    EXPECT_NE(report.file_path.value().find(path().value()), std::string::npos);
    EXPECT_EQ(report.id, std::string());
    EXPECT_FALSE(report.uploaded);
    EXPECT_EQ(report.last_upload_attempt_time, 0);
    EXPECT_EQ(report.upload_attempts, 0);
    EXPECT_FALSE(report.upload_explicitly_requested);
  }

  UploadReport(uuid, true, "test");

  {
    CrashReportDatabase::Report report;
    EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
              CrashReportDatabase::kNoError);
    EXPECT_EQ(report.uuid, uuid);
    EXPECT_NE(report.file_path.value().find(path().value()), std::string::npos);
    EXPECT_EQ(report.id, "test");
    EXPECT_TRUE(report.uploaded);
    EXPECT_NE(report.last_upload_attempt_time, 0);
    EXPECT_EQ(report.upload_attempts, 1);
    EXPECT_FALSE(report.upload_explicitly_requested);
  }
}

TEST_F(CrashReportDatabaseTest, RecordUploadAttempt) {
  std::vector<CrashReportDatabase::Report> reports(3);
  CreateCrashReport(&reports[0]);
  CreateCrashReport(&reports[1]);
  CreateCrashReport(&reports[2]);

  // Record two attempts: one successful, one not.
  UploadReport(reports[1].uuid, false, std::string());
  UploadReport(reports[2].uuid, true, "abc123");

  std::vector<CrashReportDatabase::Report> query(3);
  EXPECT_EQ(db()->LookUpCrashReport(reports[0].uuid, &query[0]),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(reports[1].uuid, &query[1]),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(reports[2].uuid, &query[2]),
            CrashReportDatabase::kNoError);

  EXPECT_EQ(query[0].id, std::string());
  EXPECT_EQ(query[1].id, std::string());
  EXPECT_EQ(query[2].id, "abc123");

  EXPECT_FALSE(query[0].uploaded);
  EXPECT_FALSE(query[1].uploaded);
  EXPECT_TRUE(query[2].uploaded);

  EXPECT_EQ(query[0].last_upload_attempt_time, 0);
  EXPECT_NE(query[1].last_upload_attempt_time, 0);
  EXPECT_NE(query[2].last_upload_attempt_time, 0);

  EXPECT_EQ(query[0].upload_attempts, 0);
  EXPECT_EQ(query[1].upload_attempts, 1);
  EXPECT_EQ(query[2].upload_attempts, 1);

  // Attempt to upload and fail again.
  UploadReport(reports[1].uuid, false, std::string());

  time_t report_2_upload_time = query[2].last_upload_attempt_time;

  EXPECT_EQ(db()->LookUpCrashReport(reports[0].uuid, &query[0]),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(reports[1].uuid, &query[1]),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(reports[2].uuid, &query[2]),
            CrashReportDatabase::kNoError);

  EXPECT_FALSE(query[0].uploaded);
  EXPECT_FALSE(query[1].uploaded);
  EXPECT_TRUE(query[2].uploaded);

  EXPECT_EQ(query[0].last_upload_attempt_time, 0);
  EXPECT_GE(query[1].last_upload_attempt_time, report_2_upload_time);
  EXPECT_EQ(query[2].last_upload_attempt_time, report_2_upload_time);

  EXPECT_EQ(query[0].upload_attempts, 0);
  EXPECT_EQ(query[1].upload_attempts, 2);
  EXPECT_EQ(query[2].upload_attempts, 1);

  // Third time's the charm: upload and succeed.
  UploadReport(reports[1].uuid, true, "666hahaha");

  time_t report_1_upload_time = query[1].last_upload_attempt_time;

  EXPECT_EQ(db()->LookUpCrashReport(reports[0].uuid, &query[0]),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(reports[1].uuid, &query[1]),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(reports[2].uuid, &query[2]),
            CrashReportDatabase::kNoError);

  EXPECT_FALSE(query[0].uploaded);
  EXPECT_TRUE(query[1].uploaded);
  EXPECT_TRUE(query[2].uploaded);

  EXPECT_EQ(query[0].last_upload_attempt_time, 0);
  EXPECT_GE(query[1].last_upload_attempt_time, report_1_upload_time);
  EXPECT_EQ(query[2].last_upload_attempt_time, report_2_upload_time);

  EXPECT_EQ(query[0].upload_attempts, 0);
  EXPECT_EQ(query[1].upload_attempts, 3);
  EXPECT_EQ(query[2].upload_attempts, 1);
}

// This test covers both query functions since they are related.
TEST_F(CrashReportDatabaseTest, GetCompletedAndNotUploadedReports) {
  std::vector<CrashReportDatabase::Report> reports(5);
  CreateCrashReport(&reports[0]);
  CreateCrashReport(&reports[1]);
  CreateCrashReport(&reports[2]);
  CreateCrashReport(&reports[3]);
  CreateCrashReport(&reports[4]);

  const UUID& report_0_uuid = reports[0].uuid;
  const UUID& report_1_uuid = reports[1].uuid;
  const UUID& report_2_uuid = reports[2].uuid;
  const UUID& report_3_uuid = reports[3].uuid;
  const UUID& report_4_uuid = reports[4].uuid;

  std::vector<CrashReportDatabase::Report> pending;
  EXPECT_EQ(db()->GetPendingReports(&pending), CrashReportDatabase::kNoError);

  std::vector<CrashReportDatabase::Report> completed;
  EXPECT_EQ(db()->GetCompletedReports(&completed),
            CrashReportDatabase::kNoError);

  EXPECT_EQ(pending.size(), reports.size());
  EXPECT_EQ(completed.size(), 0u);

  // Upload one report successfully.
  UploadReport(report_1_uuid, true, "report1");

  pending.clear();
  EXPECT_EQ(db()->GetPendingReports(&pending), CrashReportDatabase::kNoError);
  completed.clear();
  EXPECT_EQ(db()->GetCompletedReports(&completed),
            CrashReportDatabase::kNoError);

  EXPECT_EQ(pending.size(), 4u);
  ASSERT_EQ(completed.size(), 1u);

  for (const auto& report : pending) {
    EXPECT_NE(report.uuid, report_1_uuid);
    EXPECT_FALSE(report.file_path.empty());
  }
  EXPECT_EQ(completed[0].uuid, report_1_uuid);
  EXPECT_EQ(completed[0].id, "report1");
  EXPECT_EQ(completed[0].uploaded, true);
  EXPECT_GT(completed[0].last_upload_attempt_time, 0);
  EXPECT_EQ(completed[0].upload_attempts, 1);

  // Fail to upload one report.
  UploadReport(report_2_uuid, false, std::string());

  pending.clear();
  EXPECT_EQ(db()->GetPendingReports(&pending), CrashReportDatabase::kNoError);
  completed.clear();
  EXPECT_EQ(db()->GetCompletedReports(&completed),
            CrashReportDatabase::kNoError);

  EXPECT_EQ(pending.size(), 4u);
  ASSERT_EQ(completed.size(), 1u);

  for (const auto& report : pending) {
    if (report.upload_attempts != 0) {
      EXPECT_EQ(report.uuid, report_2_uuid);
      EXPECT_GT(report.last_upload_attempt_time, 0);
      EXPECT_FALSE(report.uploaded);
      EXPECT_TRUE(report.id.empty());
    }
    EXPECT_FALSE(report.file_path.empty());
  }

  // Upload a second report.
  UploadReport(report_4_uuid, true, "report_4");

  pending.clear();
  EXPECT_EQ(db()->GetPendingReports(&pending), CrashReportDatabase::kNoError);
  completed.clear();
  EXPECT_EQ(db()->GetCompletedReports(&completed),
            CrashReportDatabase::kNoError);

  EXPECT_EQ(pending.size(), 3u);
  ASSERT_EQ(completed.size(), 2u);

  // Succeed the failed report.
  UploadReport(report_2_uuid, true, "report 2");

  pending.clear();
  EXPECT_EQ(db()->GetPendingReports(&pending), CrashReportDatabase::kNoError);
  completed.clear();
  EXPECT_EQ(db()->GetCompletedReports(&completed),
            CrashReportDatabase::kNoError);

  EXPECT_EQ(pending.size(), 2u);
  ASSERT_EQ(completed.size(), 3u);

  for (const auto& report : pending) {
    EXPECT_TRUE(report.uuid == report_0_uuid || report.uuid == report_3_uuid);
    EXPECT_FALSE(report.file_path.empty());
  }

  // Skip upload for one report.
  EXPECT_EQ(db()->SkipReportUpload(
                report_3_uuid, Metrics::CrashSkippedReason::kUploadsDisabled),
            CrashReportDatabase::kNoError);

  pending.clear();
  EXPECT_EQ(db()->GetPendingReports(&pending), CrashReportDatabase::kNoError);
  completed.clear();
  EXPECT_EQ(db()->GetCompletedReports(&completed),
            CrashReportDatabase::kNoError);

  ASSERT_EQ(pending.size(), 1u);
  ASSERT_EQ(completed.size(), 4u);

  EXPECT_EQ(pending[0].uuid, report_0_uuid);

  for (const auto& report : completed) {
    if (report.uuid == report_3_uuid) {
      EXPECT_FALSE(report.uploaded);
      EXPECT_EQ(report.upload_attempts, 0);
      EXPECT_EQ(report.last_upload_attempt_time, 0);
    } else {
      EXPECT_TRUE(report.uploaded);
      EXPECT_GT(report.upload_attempts, 0);
      EXPECT_GT(report.last_upload_attempt_time, 0);
    }
    EXPECT_FALSE(report.file_path.empty());
  }
}

TEST_F(CrashReportDatabaseTest, DuelingUploads) {
  CrashReportDatabase::Report report;
  CreateCrashReport(&report);

  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report;
  EXPECT_EQ(db()->GetReportForUploading(report.uuid, &upload_report),
            CrashReportDatabase::kNoError);

  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report_2;
  EXPECT_EQ(db()->GetReportForUploading(report.uuid, &upload_report_2),
            CrashReportDatabase::kBusyError);
  EXPECT_FALSE(upload_report_2);

  EXPECT_EQ(db()->RecordUploadComplete(std::move(upload_report), std::string()),
            CrashReportDatabase::kNoError);
}

TEST_F(CrashReportDatabaseTest, UploadAlreadyUploaded) {
  CrashReportDatabase::Report report;
  CreateCrashReport(&report);

  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report;
  EXPECT_EQ(db()->GetReportForUploading(report.uuid, &upload_report),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->RecordUploadComplete(std::move(upload_report), std::string()),
            CrashReportDatabase::kNoError);

  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report_2;
  EXPECT_EQ(db()->GetReportForUploading(report.uuid, &upload_report_2),
            CrashReportDatabase::kReportNotFound);
  EXPECT_FALSE(upload_report_2.get());
}

TEST_F(CrashReportDatabaseTest, MoveDatabase) {
  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
  EXPECT_EQ(db()->PrepareNewCrashReport(&new_report),
            CrashReportDatabase::kNoError);
  UUID uuid;
  EXPECT_EQ(db()->FinishedWritingCrashReport(std::move(new_report), &uuid),
            CrashReportDatabase::kNoError);

  RelocateDatabase();

  CrashReportDatabase::Report report;
  EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
            CrashReportDatabase::kNoError);
  ExpectPreparedCrashReport(report);
}

TEST_F(CrashReportDatabaseTest, ReportRemoved) {
  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
  EXPECT_EQ(db()->PrepareNewCrashReport(&new_report),
            CrashReportDatabase::kNoError);

  UUID uuid;
  EXPECT_EQ(db()->FinishedWritingCrashReport(std::move(new_report), &uuid),
            CrashReportDatabase::kNoError);

  CrashReportDatabase::Report report;
  EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
            CrashReportDatabase::kNoError);

  EXPECT_TRUE(LoggingRemoveFile(report.file_path));

  EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
            CrashReportDatabase::kReportNotFound);
}

TEST_F(CrashReportDatabaseTest, DeleteReport) {
  CrashReportDatabase::Report keep_pending;
  CrashReportDatabase::Report delete_pending;
  CrashReportDatabase::Report keep_completed;
  CrashReportDatabase::Report delete_completed;

  CreateCrashReport(&keep_pending);
  CreateCrashReport(&delete_pending);
  CreateCrashReport(&keep_completed);
  CreateCrashReport(&delete_completed);

  EXPECT_TRUE(FileExists(keep_pending.file_path));
  EXPECT_TRUE(FileExists(delete_pending.file_path));
  EXPECT_TRUE(FileExists(keep_completed.file_path));
  EXPECT_TRUE(FileExists(delete_completed.file_path));

  UploadReport(keep_completed.uuid, true, "1");
  UploadReport(delete_completed.uuid, true, "2");

  EXPECT_EQ(db()->LookUpCrashReport(keep_completed.uuid, &keep_completed),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(delete_completed.uuid, &delete_completed),
            CrashReportDatabase::kNoError);

  EXPECT_TRUE(FileExists(keep_completed.file_path));
  EXPECT_TRUE(FileExists(delete_completed.file_path));

  EXPECT_EQ(db()->DeleteReport(delete_pending.uuid),
            CrashReportDatabase::kNoError);
  EXPECT_FALSE(FileExists(delete_pending.file_path));
  EXPECT_EQ(db()->LookUpCrashReport(delete_pending.uuid, &delete_pending),
            CrashReportDatabase::kReportNotFound);
  EXPECT_EQ(db()->DeleteReport(delete_pending.uuid),
            CrashReportDatabase::kReportNotFound);

  EXPECT_EQ(db()->DeleteReport(delete_completed.uuid),
            CrashReportDatabase::kNoError);
  EXPECT_FALSE(FileExists(delete_completed.file_path));
  EXPECT_EQ(db()->LookUpCrashReport(delete_completed.uuid, &delete_completed),
            CrashReportDatabase::kReportNotFound);
  EXPECT_EQ(db()->DeleteReport(delete_completed.uuid),
            CrashReportDatabase::kReportNotFound);

  EXPECT_EQ(db()->LookUpCrashReport(keep_pending.uuid, &keep_pending),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(keep_completed.uuid, &keep_completed),
            CrashReportDatabase::kNoError);
}

TEST_F(CrashReportDatabaseTest, DeleteReportEmptyingDatabase) {
  CrashReportDatabase::Report report;
  CreateCrashReport(&report);

  EXPECT_TRUE(FileExists(report.file_path));

  UploadReport(report.uuid, true, "1");

  EXPECT_EQ(db()->LookUpCrashReport(report.uuid, &report),
            CrashReportDatabase::kNoError);

  EXPECT_TRUE(FileExists(report.file_path));

  // This causes an empty database to be written, make sure this is handled.
  EXPECT_EQ(db()->DeleteReport(report.uuid), CrashReportDatabase::kNoError);
  EXPECT_FALSE(FileExists(report.file_path));
}

TEST_F(CrashReportDatabaseTest, ReadEmptyDatabase) {
  CrashReportDatabase::Report report;
  CreateCrashReport(&report);
  EXPECT_EQ(db()->DeleteReport(report.uuid), CrashReportDatabase::kNoError);

  // Deleting and the creating another report causes an empty database to be
  // loaded. Make sure this is handled.

  CrashReportDatabase::Report report2;
  CreateCrashReport(&report2);
}

TEST_F(CrashReportDatabaseTest, RequestUpload) {
  std::vector<CrashReportDatabase::Report> reports(2);
  CreateCrashReport(&reports[0]);
  CreateCrashReport(&reports[1]);

  const UUID& report_0_uuid = reports[0].uuid;
  const UUID& report_1_uuid = reports[1].uuid;

  // Skipped report gets back to pending state after RequestUpload is called.
  EXPECT_EQ(db()->SkipReportUpload(
                report_1_uuid, Metrics::CrashSkippedReason::kUploadsDisabled),
            CrashReportDatabase::kNoError);

  std::vector<CrashReportDatabase::Report> pending_reports;
  CrashReportDatabase::OperationStatus os =
      db()->GetPendingReports(&pending_reports);
  EXPECT_EQ(os, CrashReportDatabase::kNoError);
  ASSERT_EQ(pending_reports.size(), 1u);
  EXPECT_EQ(report_0_uuid, pending_reports[0].uuid);

  pending_reports.clear();
  EXPECT_EQ(RequestUpload(report_1_uuid), CrashReportDatabase::kNoError);
  os = db()->GetPendingReports(&pending_reports);
  EXPECT_EQ(os, CrashReportDatabase::kNoError);
  ASSERT_EQ(pending_reports.size(), 2u);

  // Check individual reports.
  const CrashReportDatabase::Report* explicitly_requested_report;
  const CrashReportDatabase::Report* pending_report;
  if (pending_reports[0].uuid == report_0_uuid) {
    pending_report = &pending_reports[0];
    explicitly_requested_report = &pending_reports[1];
  } else {
    pending_report = &pending_reports[1];
    explicitly_requested_report = &pending_reports[0];
  }

  EXPECT_EQ(pending_report->uuid, report_0_uuid);
  EXPECT_FALSE(pending_report->upload_explicitly_requested);

  EXPECT_EQ(explicitly_requested_report->uuid, report_1_uuid);
  EXPECT_TRUE(explicitly_requested_report->upload_explicitly_requested);

  // Explicitly requested reports will not have upload_explicitly_requested bit
  // after getting skipped.
  EXPECT_EQ(db()->SkipReportUpload(
                report_1_uuid, Metrics::CrashSkippedReason::kUploadsDisabled),
            CrashReportDatabase::kNoError);
  CrashReportDatabase::Report report;
  EXPECT_EQ(db()->LookUpCrashReport(report_1_uuid, &report),
            CrashReportDatabase::kNoError);
  EXPECT_FALSE(report.upload_explicitly_requested);

  // Pending report gets correctly affected after RequestUpload is called.
  pending_reports.clear();
  EXPECT_EQ(RequestUpload(report_0_uuid), CrashReportDatabase::kNoError);
  os = db()->GetPendingReports(&pending_reports);
  EXPECT_EQ(os, CrashReportDatabase::kNoError);
  EXPECT_EQ(pending_reports.size(), 1u);
  EXPECT_EQ(report_0_uuid, pending_reports[0].uuid);
  EXPECT_TRUE(pending_reports[0].upload_explicitly_requested);

  // Already uploaded report cannot be requested for the new upload.
  UploadReport(report_0_uuid, true, "1");
  EXPECT_EQ(RequestUpload(report_0_uuid),
            CrashReportDatabase::kCannotRequestUpload);
}

TEST_F(CrashReportDatabaseTest, Attachments) {
#if defined(OS_APPLE) || defined(OS_WIN)
  // Attachments aren't supported on Mac and Windows yet.
  GTEST_SKIP();
#else
  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
  ASSERT_EQ(db()->PrepareNewCrashReport(&new_report),
            CrashReportDatabase::kNoError);

  FileWriter* attach_some_file = new_report->AddAttachment("some_file");
  ASSERT_NE(attach_some_file, nullptr);
  static constexpr char test_data[] = "test data";
  attach_some_file->Write(test_data, sizeof(test_data));

  FileWriter* failed_attach = new_report->AddAttachment("not/a valid fi!e");
  EXPECT_EQ(failed_attach, nullptr);

  UUID expect_uuid = new_report->ReportID();
  UUID uuid;
  ASSERT_EQ(db()->FinishedWritingCrashReport(std::move(new_report), &uuid),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(uuid, expect_uuid);

  CrashReportDatabase::Report report;
  EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
            CrashReportDatabase::kNoError);
  ExpectPreparedCrashReport(report);

  std::vector<CrashReportDatabase::Report> reports;
  EXPECT_EQ(db()->GetPendingReports(&reports), CrashReportDatabase::kNoError);
  ASSERT_EQ(reports.size(), 1u);
  EXPECT_EQ(reports[0].uuid, report.uuid);

  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report;
  ASSERT_EQ(db()->GetReportForUploading(reports[0].uuid, &upload_report),
            CrashReportDatabase::kNoError);
  std::map<std::string, FileReader*> result_attachments =
      upload_report->GetAttachments();
  EXPECT_EQ(result_attachments.size(), 1u);
  EXPECT_NE(result_attachments.find("some_file"), result_attachments.end());
  char result_buffer[sizeof(test_data)];
  result_attachments["some_file"]->Read(result_buffer, sizeof(result_buffer));
  EXPECT_EQ(memcmp(test_data, result_buffer, sizeof(test_data)), 0);
#endif
}

TEST_F(CrashReportDatabaseTest, OrphanedAttachments) {
#if defined(OS_APPLE) || defined(OS_WIN)
  // Attachments aren't supported on Mac and Windows yet.
  GTEST_SKIP();
#else
  // TODO: This is using paths that are specific to the generic implementation
  // and will need to be generalized for Mac and Windows.
  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
  ASSERT_EQ(db()->PrepareNewCrashReport(&new_report),
            CrashReportDatabase::kNoError);

  FileWriter* file1 = new_report->AddAttachment("file1");
  ASSERT_NE(file1, nullptr);
  FileWriter* file2 = new_report->AddAttachment("file2");
  ASSERT_NE(file2, nullptr);

  UUID expect_uuid = new_report->ReportID();
  UUID uuid;
  ASSERT_EQ(db()->FinishedWritingCrashReport(std::move(new_report), &uuid),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(uuid, expect_uuid);

  CrashReportDatabase::Report report;
  ASSERT_EQ(db()->LookUpCrashReport(uuid, &report),
            CrashReportDatabase::kNoError);

  ASSERT_TRUE(LoggingRemoveFile(report.file_path));

  ASSERT_TRUE(LoggingRemoveFile(base::FilePath(
      report.file_path.RemoveFinalExtension().value() + ".meta")));

  ASSERT_EQ(db()->LookUpCrashReport(uuid, &report),
            CrashReportDatabase::kReportNotFound);

  base::FilePath report_attachments_dir(
      path().Append("attachments").Append(uuid.ToString()));
  base::FilePath file_path1(report_attachments_dir.Append("file1"));
  base::FilePath file_path2(report_attachments_dir.Append("file2"));
  EXPECT_TRUE(FileExists(file_path1));
  EXPECT_TRUE(FileExists(file_path1));

  EXPECT_EQ(db()->CleanDatabase(0), 0);

  EXPECT_FALSE(FileExists(file_path1));
  EXPECT_FALSE(FileExists(file_path2));
  EXPECT_FALSE(FileExists(report_attachments_dir));
#endif
}

// This test uses knowledge of the database format to break it, so it only
// applies to the unfified database implementation.
#if !defined(OS_APPLE) && !defined(OS_WIN)
TEST_F(CrashReportDatabaseTest, CleanBrokenDatabase) {
  // Remove report files if metadata goes missing.
  CrashReportDatabase::Report report;
  ASSERT_NO_FATAL_FAILURE(CreateCrashReport(&report));

  const base::FilePath metadata(
      report.file_path.RemoveFinalExtension().value() +
      FILE_PATH_LITERAL(".meta"));
  ASSERT_TRUE(PathExists(report.file_path));
  ASSERT_TRUE(PathExists(metadata));

  ASSERT_TRUE(LoggingRemoveFile(metadata));
  EXPECT_EQ(db()->CleanDatabase(0), 1);

  EXPECT_FALSE(PathExists(report.file_path));
  EXPECT_FALSE(PathExists(metadata));

  // Remove metadata files if reports go missing.
  ASSERT_NO_FATAL_FAILURE(CreateCrashReport(&report));
  const base::FilePath metadata2(
      report.file_path.RemoveFinalExtension().value() +
      FILE_PATH_LITERAL(".meta"));
  ASSERT_TRUE(PathExists(report.file_path));
  ASSERT_TRUE(PathExists(metadata2));

  ASSERT_TRUE(LoggingRemoveFile(report.file_path));
  EXPECT_EQ(db()->CleanDatabase(0), 1);

  EXPECT_FALSE(PathExists(report.file_path));
  EXPECT_FALSE(PathExists(metadata2));

  // Remove stale new files.
  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
  EXPECT_EQ(db()->PrepareNewCrashReport(&new_report),
            CrashReportDatabase::kNoError);
  new_report->Writer()->Close();
  EXPECT_EQ(db()->CleanDatabase(0), 1);

  // Remove stale lock files and their associated reports.
  ASSERT_NO_FATAL_FAILURE(CreateCrashReport(&report));
  const base::FilePath metadata3(
      report.file_path.RemoveFinalExtension().value() +
      FILE_PATH_LITERAL(".meta"));
  ASSERT_TRUE(PathExists(report.file_path));
  ASSERT_TRUE(PathExists(metadata3));

  const base::FilePath lockpath(
      report.file_path.RemoveFinalExtension().value() +
      FILE_PATH_LITERAL(".lock"));
  ScopedFileHandle handle(LoggingOpenFileForWrite(
      lockpath, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly));
  ASSERT_TRUE(handle.is_valid());

  time_t expired_timestamp = time(nullptr) - 60 * 60 * 24 * 3;

  ASSERT_TRUE(LoggingWriteFile(
      handle.get(), &expired_timestamp, sizeof(expired_timestamp)));
  ASSERT_TRUE(LoggingCloseFile(handle.release()));

  EXPECT_EQ(db()->CleanDatabase(0), 1);

  EXPECT_FALSE(PathExists(report.file_path));
  EXPECT_FALSE(PathExists(metadata3));
}
#endif  // !OS_APPLE && !OS_WIN

TEST_F(CrashReportDatabaseTest, TotalSize_MainReportOnly) {
  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
  ASSERT_EQ(db()->PrepareNewCrashReport(&new_report),
            CrashReportDatabase::kNoError);

  // Main report.
  static constexpr char main_report_data[] = "dlbvandslhb";
  ASSERT_TRUE(
      new_report->Writer()->Write(main_report_data, sizeof(main_report_data)));

  UUID uuid;
  ASSERT_EQ(db()->FinishedWritingCrashReport(std::move(new_report), &uuid),
            CrashReportDatabase::kNoError);

  CrashReportDatabase::Report report;
  ASSERT_EQ(db()->LookUpCrashReport(uuid, &report),
            CrashReportDatabase::kNoError);

  EXPECT_EQ(report.total_size, sizeof(main_report_data));
}

TEST_F(CrashReportDatabaseTest, GetReportSize_RightSizeWithAttachments) {
#if defined(OS_APPLE) || defined(OS_WIN)
  // Attachments aren't supported on Mac and Windows yet.
  return;
#else
  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
  ASSERT_EQ(db()->PrepareNewCrashReport(&new_report),
            CrashReportDatabase::kNoError);

  // Main report.
  static constexpr char main_report_data[] = "dlbvandslhb";
  ASSERT_TRUE(
      new_report->Writer()->Write(main_report_data, sizeof(main_report_data)));

  // First attachment.
  FileWriter* attachment_1 = new_report->AddAttachment("my_attachment_1");
  ASSERT_NE(attachment_1, nullptr);
  static constexpr char attachment_1_data[] = "vKDnidhvbiudshoihbvdsoiuh nhh";
  attachment_1->Write(attachment_1_data, sizeof(attachment_1_data));

  // Second attachment.
  FileWriter* attachment_2 = new_report->AddAttachment("my_attachment_2");
  ASSERT_NE(attachment_2, nullptr);
  static constexpr char attachment_2_data[] = "sgvsvgusiyguysigfkhpmo-[";
  attachment_2->Write(attachment_2_data, sizeof(attachment_2_data));

  UUID uuid;
  ASSERT_EQ(db()->FinishedWritingCrashReport(std::move(new_report), &uuid),
            CrashReportDatabase::kNoError);

  CrashReportDatabase::Report report;
  ASSERT_EQ(db()->LookUpCrashReport(uuid, &report),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(report.total_size,
            sizeof(main_report_data) + sizeof(attachment_1_data) +
                sizeof(attachment_2_data));
#endif
}

}  // namespace
}  // namespace test
}  // namespace crashpad
