// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "arc/apk-cache/cache_cleaner_db.h"

#include <base/bind.h>
#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/optional.h>
#include <base/time/time.h>
#include <gtest/gtest.h>
#include <sqlite3.h>

#include "arc/apk-cache/apk_cache_database.h"
#include "arc/apk-cache/apk_cache_database_test_utils.h"
#include "arc/apk-cache/apk_cache_utils.h"

namespace apk_cache {

namespace {

constexpr char kBrokenDatabaseContent[] = "test broken db file content";
constexpr char kTestSessionSource[] = "unit_test_session_source";
constexpr int64_t kTestSessionId = 123;

constexpr int64_t kTestBaseApkId = 1234;
constexpr int64_t kTestAttachmentId = 1235;
constexpr char kTestPackageName[] = "com.package.test";
constexpr int64_t kTestVersionCode = 1234;
constexpr char kTestAttachmentType[] = "test.foo.bar";
constexpr char kTestFileContent[] = "test file content";
constexpr char kTestFileHash[] = "2Q7xZR_Z51Y-GhRQoWvXhOmn4tPfD1p5jfwb33CmSuo";
constexpr int32_t kTestPackagePriority = 100;

bool CreateSession(const base::FilePath& db_path, int64_t id, int32_t status) {
  Session session;
  session.id = id;
  session.source = kTestSessionSource;
  session.timestamp = base::Time::Now();
  session.status = status;
  return InsertSessionForTesting(db_path, session);
}

bool CreateFileEntry(const base::FilePath& db_path,
                     const base::FilePath& files_path,
                     int64_t id,
                     const std::string& package_name,
                     int64_t version_code,
                     const std::string& type) {
  FileEntry file_entry;
  file_entry.id = id;
  file_entry.package_name = package_name;
  file_entry.version_code = version_code;
  file_entry.type = type;
  file_entry.size = strlen(kTestFileContent);
  file_entry.hash = std::string(kTestFileHash);
  file_entry.access_time = base::Time::Now();
  file_entry.priority = kTestPackagePriority;
  file_entry.session_id = kTestSessionId;
  if (!InsertFileEntryForTesting(db_path, file_entry))
    return false;

  base::FilePath file_path = files_path.Append(GetFileNameById(id));
  return base::WriteFile(file_path, kTestFileContent, strlen(kTestFileContent));
}

bool CreateValidPackage(const base::FilePath& db_path,
                        const base::FilePath& files_path) {
  return CreateSession(db_path, kTestSessionId, kSessionStatusClosed) &&
         CreateFileEntry(db_path, files_path, kTestBaseApkId, kTestPackageName,
                         kTestVersionCode, kFileTypeBaseApk) &&
         CreateFileEntry(db_path, files_path, kTestAttachmentId,
                         kTestPackageName, kTestVersionCode,
                         kTestAttachmentType);
}

}  // namespace

class CacheCleanerDBTest : public testing::Test {
 public:
  const base::FilePath& temp_path() const { return temp_dir_.GetPath(); }

 protected:
  CacheCleanerDBTest() = default;

  // Not copyable or movable.
  CacheCleanerDBTest(const CacheCleanerDBTest&) = delete;
  CacheCleanerDBTest& operator=(const CacheCleanerDBTest&) = delete;

  void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
  void TearDown() override { ASSERT_TRUE(temp_dir_.Delete()); }

 private:
  base::ScopedTempDir temp_dir_;
};

// If database does not exist, files directory should be removed.
TEST_F(CacheCleanerDBTest, DatabaseNotExist) {
  // Create files directory.
  base::FilePath files_path = temp_path().Append(kFilesBase);
  ASSERT_TRUE(base::CreateDirectory(files_path));
  // Write a random file to files directory.
  base::FilePath file_path = files_path.Append("test");
  ASSERT_TRUE(
      base::WriteFile(file_path, kTestFileContent, strlen(kTestFileContent)));
  // Clean.
  EXPECT_TRUE(OpaqueFilesCleaner(temp_path()).Clean());
  // Files directory should be removed.
  EXPECT_FALSE(base::PathExists(files_path));
}

// If database is empty, files directory should be removed.
TEST_F(CacheCleanerDBTest, EmptyDatabase) {
  // Write empty database file.
  base::FilePath db_path = temp_path().Append(kDatabaseFile);
  ASSERT_TRUE(base::WriteFile(db_path, "\0", 1));
  ASSERT_TRUE(base::PathExists(db_path));
  // Create files directory.
  base::FilePath files_path = temp_path().Append(kFilesBase);
  ASSERT_TRUE(base::CreateDirectory(files_path));
  // Write a random file to files directory.
  base::FilePath file_path = files_path.Append("test");
  ASSERT_TRUE(
      base::WriteFile(file_path, kTestFileContent, strlen(kTestFileContent)));
  // Clean.
  EXPECT_TRUE(OpaqueFilesCleaner(temp_path()).Clean());
  // Files directory should be removed.
  EXPECT_FALSE(base::PathExists(files_path));
}

// Correct database structure should pass integrity test.
TEST_F(CacheCleanerDBTest, ApkCacheDatabase) {
  base::FilePath db_path = temp_path().Append(kDatabaseFile);
  ASSERT_EQ(CreateDatabaseForTesting(db_path), SQLITE_OK);
  EXPECT_TRUE(base::PathExists(db_path));
  EXPECT_TRUE(OpaqueFilesCleaner(temp_path()).Clean());
}

// If database file is broken, it should be removed with files directory.
TEST_F(CacheCleanerDBTest, BrokenDatabaseFile) {
  // Write random content to database file.
  base::FilePath db_path = temp_path().Append(kDatabaseFile);
  base::WriteFile(db_path, kBrokenDatabaseContent,
                  strlen(kBrokenDatabaseContent));
  EXPECT_TRUE(base::PathExists(db_path));
  // Create files directory.
  base::FilePath files_path = temp_path().Append(kFilesBase);
  ASSERT_TRUE(base::CreateDirectory(files_path));
  // Write a random file to files directory.
  base::FilePath file_path = files_path.Append("test");
  ASSERT_TRUE(
      base::WriteFile(file_path, kTestFileContent, strlen(kTestFileContent)));
  // Clean.
  EXPECT_TRUE(OpaqueFilesCleaner(temp_path()).Clean());
  // Both database file and files directory should be removed.
  EXPECT_FALSE(base::PathExists(db_path));
  EXPECT_FALSE(base::PathExists(files_path));
}

// Cache cleaner should create a session before cleaning.
TEST_F(CacheCleanerDBTest, CacheCleanerSession) {
  base::FilePath db_path = temp_path().Append(kDatabaseFile);
  ASSERT_EQ(CreateDatabaseForTesting(db_path), SQLITE_OK);
  EXPECT_TRUE(base::PathExists(db_path));
  // Clean.
  OpaqueFilesCleaner cleaner(temp_path());
  EXPECT_TRUE(cleaner.Clean());
  // Cache cleaner session should be created.
  ApkCacheDatabase db(db_path);
  ASSERT_EQ(db.Init(), SQLITE_OK);
  auto sessions = db.GetSessions();
  ASSERT_TRUE(sessions);
  ASSERT_EQ(sessions->size(), 1);
  ASSERT_EQ((*sessions)[0].source, kCacheCleanerSessionSource);
}

// If an open session is not expired, cleaner should exit.
TEST_F(CacheCleanerDBTest, OtherSessionActive) {
  base::FilePath db_path = temp_path().Append(kDatabaseFile);
  ASSERT_EQ(CreateDatabaseForTesting(db_path), SQLITE_OK);
  EXPECT_TRUE(base::PathExists(db_path));
  // Create an open session.
  ASSERT_TRUE(CreateSession(db_path, kTestSessionId, kSessionStatusOpen));
  // Clean.
  OpaqueFilesCleaner cleaner(temp_path());
  EXPECT_TRUE(cleaner.Clean());
  // Cache cleaner session should not be created.
  ApkCacheDatabase db(db_path);
  ASSERT_EQ(db.Init(), SQLITE_OK);
  auto sessions = db.GetSessions();
  ASSERT_TRUE(sessions);
  for (Session session : *sessions)
    EXPECT_NE(session.source, kCacheCleanerSessionSource);
}

// Session without file entries should be removed.
TEST_F(CacheCleanerDBTest, SessionWithoutFileEntries) {
  base::FilePath db_path = temp_path().Append(kDatabaseFile);
  ASSERT_EQ(CreateDatabaseForTesting(db_path), SQLITE_OK);
  EXPECT_TRUE(base::PathExists(db_path));
  // Create session.
  CreateSession(db_path, kTestSessionId, kSessionStatusClosed);
  // Clean.
  EXPECT_TRUE(OpaqueFilesCleaner(temp_path()).Clean());
  // Test session should be removed.
  ApkCacheDatabase db(db_path);
  ASSERT_EQ(db.Init(), SQLITE_OK);
  auto sessions = db.GetSessions();
  ASSERT_TRUE(sessions);
  bool session_exists = false;
  for (Session session : *sessions)
    if (session.id == kTestSessionId) {
      session_exists = true;
      break;
    }
  EXPECT_FALSE(session_exists);
}

// Expired open sessions should be removed.
TEST_F(CacheCleanerDBTest, ExpiredOpenSessions) {
  base::FilePath db_path = temp_path().Append(kDatabaseFile);
  ASSERT_EQ(CreateDatabaseForTesting(db_path), SQLITE_OK);
  EXPECT_TRUE(base::PathExists(db_path));
  // Create valid package.
  base::FilePath files_path = temp_path().Append(kFilesBase);
  ASSERT_TRUE(base::CreateDirectory(files_path));
  EXPECT_TRUE(CreateValidPackage(db_path, files_path));
  // Change session status to open.
  UpdateSessionStatusForTesting(db_path, kTestSessionId, kSessionStatusOpen);
  // Let session expire.
  UpdateSessionTimestampForTesting(
      db_path, kTestSessionId,
      base::Time::Now() - kSessionMaxAge - base::TimeDelta::FromSeconds(1));
  // Clean.
  EXPECT_TRUE(OpaqueFilesCleaner(temp_path()).Clean());
  // Test session should be removed.
  ApkCacheDatabase db(db_path);
  ASSERT_EQ(db.Init(), SQLITE_OK);
  auto sessions = db.GetSessions();
  ASSERT_TRUE(sessions);
  bool session_exists = false;
  for (Session session : *sessions)
    if (session.id == kTestSessionId) {
      session_exists = true;
      break;
    }
  EXPECT_FALSE(session_exists);
  // Package should be removed.
  auto file_entries = db.GetFileEntries();
  ASSERT_TRUE(file_entries);
  EXPECT_EQ(file_entries->size(), 0);
}

// Valid package should not be removed.
TEST_F(CacheCleanerDBTest, ValidPackage) {
  base::FilePath db_path = temp_path().Append(kDatabaseFile);
  ASSERT_EQ(CreateDatabaseForTesting(db_path), SQLITE_OK);
  EXPECT_TRUE(base::PathExists(db_path));
  // Create valid package.
  base::FilePath files_path = temp_path().Append(kFilesBase);
  ASSERT_TRUE(base::CreateDirectory(files_path));
  EXPECT_TRUE(CreateValidPackage(db_path, files_path));
  // Clean.
  EXPECT_TRUE(OpaqueFilesCleaner(temp_path()).Clean());
  // Package should still exist.
  ApkCacheDatabase db(db_path);
  ASSERT_EQ(db.Init(), SQLITE_OK);
  auto file_entries = db.GetFileEntries();
  ASSERT_TRUE(file_entries);
  EXPECT_EQ(file_entries->size(), 2);
}

// If a file is expired, the whole package should be removed.
TEST_F(CacheCleanerDBTest, ExpiredFile) {
  base::FilePath db_path = temp_path().Append(kDatabaseFile);
  ASSERT_EQ(CreateDatabaseForTesting(db_path), SQLITE_OK);
  EXPECT_TRUE(base::PathExists(db_path));
  // Create valid package.
  base::FilePath files_path = temp_path().Append(kFilesBase);
  ASSERT_TRUE(base::CreateDirectory(files_path));
  EXPECT_TRUE(CreateValidPackage(db_path, files_path));
  // Update timestamp so that base APK is expired.
  base::Time access_time =
      base::Time::Now() - kValidityPeriod - base::TimeDelta::FromSeconds(1);
  ASSERT_TRUE(
      UpdateFileAccessTimeForTesting(db_path, kTestBaseApkId, access_time));
  // Clean.
  EXPECT_TRUE(OpaqueFilesCleaner(temp_path()).Clean());
  // Package should be removed.
  ApkCacheDatabase db(db_path);
  ASSERT_EQ(db.Init(), SQLITE_OK);
  auto file_entries = db.GetFileEntries();
  ASSERT_TRUE(file_entries);
  EXPECT_EQ(file_entries->size(), 0);
}

// If a file does not have a record in database, it should be removed.
TEST_F(CacheCleanerDBTest, FileWithoutRecord) {
  base::FilePath db_path = temp_path().Append(kDatabaseFile);
  ASSERT_EQ(CreateDatabaseForTesting(db_path), SQLITE_OK);
  EXPECT_TRUE(base::PathExists(db_path));
  // Create valid package.
  base::FilePath files_path = temp_path().Append(kFilesBase);
  ASSERT_TRUE(base::CreateDirectory(files_path));
  EXPECT_TRUE(CreateValidPackage(db_path, files_path));
  // Create a random file in files directory.
  base::FilePath random_file = files_path.Append("foobar");
  base::WriteFile(random_file, kTestFileContent, strlen(kTestFileContent));
  // The file should exist.
  EXPECT_TRUE(base::PathExists(random_file));
  // Clean.
  EXPECT_TRUE(OpaqueFilesCleaner(temp_path()).Clean());
  // The file should be removed.
  EXPECT_FALSE(base::PathExists(random_file));
}

// If a directory appears in files directory, it should be removed.
TEST_F(CacheCleanerDBTest, DirectoryInFiles) {
  base::FilePath db_path = temp_path().Append(kDatabaseFile);
  ASSERT_EQ(CreateDatabaseForTesting(db_path), SQLITE_OK);
  EXPECT_TRUE(base::PathExists(db_path));
  // Create valid package.
  base::FilePath files_path = temp_path().Append(kFilesBase);
  ASSERT_TRUE(base::CreateDirectory(files_path));
  EXPECT_TRUE(CreateValidPackage(db_path, files_path));
  // Create a random directory in files directory.
  base::FilePath random_dir = files_path.Append("foobar");
  base::CreateDirectory(random_dir);
  base::FilePath random_file = random_dir.Append("test");
  ASSERT_TRUE(
      base::WriteFile(random_file, kTestFileContent, strlen(kTestFileContent)));
  // The directory should exist.
  EXPECT_TRUE(base::PathExists(random_dir));
  EXPECT_TRUE(base::PathExists(random_file));
  // Clean.
  EXPECT_TRUE(OpaqueFilesCleaner(temp_path()).Clean());
  // The directory should be removed.
  EXPECT_FALSE(base::PathExists(random_dir));
  EXPECT_FALSE(base::PathExists(random_file));
}

}  // namespace apk_cache
