// 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() {}

 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_;

  DISALLOW_COPY_AND_ASSIGN(CrashReportDatabaseTest);
};

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_MACOSX) || 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_MACOSX) || 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_MACOSX) && !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.get()));
  ignore_result(handle.release());

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

  EXPECT_FALSE(PathExists(report.file_path));
  EXPECT_FALSE(PathExists(metadata3));
}
#endif  // !OS_MACOSX && !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_MACOSX) || 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
