// Copyright 2018 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.h"

#include <set>
#include <string>
#include <vector>

#include <base/files/file_enumerator.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/strings/stringprintf.h>
#include <base/time/time.h>
#include <gtest/gtest.h>

namespace apk_cache {

namespace {

constexpr char kPackage0[] = "com.example.package0";
constexpr char kPackage1[] = "com.example.package1";
constexpr int kObbVersion = 1;

bool CreateFile(const base::FilePath& file_path) {
  return base::WriteFile(file_path, "", 0) == 0;
}

bool DeleteFile(const base::FilePath& file_path) {
  return base::DeleteFile(file_path);
}

bool CreateDir(const base::FilePath& dir_path) {
  return base::CreateDirectory(dir_path);
}

std::string GetApkFileName(const std::string& package_name) {
  return package_name + kApkExtension;
}

std::string GetMainObbFileName(const std::string& package_name, int version) {
  return base::StringPrintf("%s%d.%s%s", kMainObbPrefix, version,
                            package_name.c_str(), kObbExtension);
}

std::string GetPatchObbFileName(const std::string& package_name, int version) {
  return base::StringPrintf("%s%d.%s%s", kPatchObbPrefix, version,
                            package_name.c_str(), kObbExtension);
}

std::string TimeToString(const base::Time& time) {
  base::Time::Exploded exploded_time;
  time.UTCExplode(&exploded_time);
  // We can't use base::Time::operator<< here because the ARC cache app writes
  // access time into JSON file following the defined time format
  // that is different from what operator<< provides.
  return base::StringPrintf(
      "%04d-%02d-%02d %02d:%02d:%02d.%03d", exploded_time.year,
      exploded_time.month, exploded_time.day_of_month, exploded_time.hour,
      exploded_time.minute, exploded_time.second, exploded_time.millisecond);
}

bool WriteAttributes(const base::FilePath& dir_path,
                     const std::string& package_name,
                     const base::Time& time) {
  const std::string json_content = base::StringPrintf(
      "{\n"
      "  \"attributes\": {\n"
      "    \"package_name\": \"%s\",\n"
      "    \"atime\": \"%s\"\n"
      "  }\n"
      "}",
      package_name.c_str(), TimeToString(time).c_str());

  const int written_bytes = base::WriteFile(
      dir_path.Append(kAttrJson), json_content.c_str(), json_content.length());
  return written_bytes == json_content.length();
}

bool CreateValidPackage(const base::FilePath& cache_root_path,
                        const std::string& package_name) {
  const base::FilePath package_path = cache_root_path.Append(package_name);
  return CreateDir(package_path) &&
         CreateFile(package_path.Append(GetApkFileName(package_name))) &&
         CreateFile(package_path.Append(
             GetMainObbFileName(package_name, kObbVersion))) &&
         CreateFile(package_path.Append(
             GetPatchObbFileName(package_name, kObbVersion))) &&
         WriteAttributes(package_path, package_name, base::Time::Now());
}

void VerifyCache(const base::FilePath& cache_root_path,
                 const std::set<std::string>& expected_package_name_set) {
  {
    base::FileEnumerator files(
        cache_root_path, false /* recursive */,
        base::FileEnumerator::FILES | base::FileEnumerator::SHOW_SYM_LINKS);
    base::FilePath unnecessary_file_path = files.Next();
    if (!unnecessary_file_path.empty())
      FAIL() << "Cache root should not contain any files but it contains "
             << unnecessary_file_path.value();
  }

  {
    base::FileEnumerator dirs(cache_root_path, false /* recursive */,
                              base::FileEnumerator::DIRECTORIES |
                                  base::FileEnumerator::SHOW_SYM_LINKS);
    std::set<std::string> available_package_name_set;

    for (base::FilePath dir_path = dirs.Next(); !dir_path.empty();
         dir_path = dirs.Next()) {
      available_package_name_set.insert(dir_path.BaseName().value());
    }

    EXPECT_EQ(available_package_name_set, expected_package_name_set);
  }
}

}  // namespace

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

 protected:
  CacheCleanerTest() = default;
  CacheCleanerTest(const CacheCleanerTest&) = delete;
  CacheCleanerTest& operator=(const CacheCleanerTest&) = delete;

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

 private:
  base::ScopedTempDir temp_dir_;
};

// Creates 2 valid packages and checks that none of them is deleted.
TEST_F(CacheCleanerTest, ValidPackage) {
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage1));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {kPackage0, kPackage1});
}

// Checks that absence of main OBB file does not lead to the deletion.
TEST_F(CacheCleanerTest, NoMainObb) {
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));
  ASSERT_TRUE(apk_cache::DeleteFile(temp_path().Append(kPackage0).Append(
      GetMainObbFileName(kPackage0, kObbVersion))));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {kPackage0});
}

// Checks that absence of patch OBB file does not lead to the deletion.
TEST_F(CacheCleanerTest, NoPatchObb) {
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));
  ASSERT_TRUE(apk_cache::DeleteFile(temp_path().Append(kPackage0).Append(
      GetPatchObbFileName(kPackage0, kObbVersion))));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {kPackage0});
}

// Checks that the files in cache root are deleted.
TEST_F(CacheCleanerTest, OddFileInRoot) {
  ASSERT_TRUE(CreateFile(temp_path().Append("odd.file.1")));
  ASSERT_TRUE(CreateFile(temp_path().Append("odd.file.2")));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {});
}

// Checks that empty package directory is deleted.
TEST_F(CacheCleanerTest, EmptyPackage) {
  ASSERT_TRUE(CreateDir(temp_path().Append(kPackage0)));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {});
}

// No attr.json must lead to the package removal.
TEST_F(CacheCleanerTest, NoAttrJson) {
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));
  ASSERT_TRUE(
      apk_cache::DeleteFile(temp_path().Append(kPackage0).Append(kAttrJson)));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {});
}

// No APK file leads to the package removal.
TEST_F(CacheCleanerTest, NoApk) {
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));
  ASSERT_TRUE(apk_cache::DeleteFile(
      temp_path().Append(kPackage0).Append(GetApkFileName(kPackage0))));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {});
}

// If there are 2 or more main OBB files in the package, it must be deleted.
TEST_F(CacheCleanerTest, ExtraMainObbFile) {
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));
  ASSERT_TRUE(CreateFile(
      temp_path().Append(kPackage0).Append(GetMainObbFileName(kPackage0, 99))));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {});
}

// If there are 2 or more patch OBB files in the package, it must be deleted.
TEST_F(CacheCleanerTest, ExtraPatchObbFile) {
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));
  ASSERT_TRUE(CreateFile(temp_path().Append(kPackage0).Append(
      GetPatchObbFileName(kPackage0, 99))));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {});
}

// If package contains any odd file, the package is to be deleted.
TEST_F(CacheCleanerTest, ExtraRandomFile) {
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));
  ASSERT_TRUE(CreateFile(temp_path().Append(kPackage0).Append("blabla.file")));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {});
}

// If package contains any odd dir, the package is to be deleted.
TEST_F(CacheCleanerTest, ExtraRandomDir) {
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));
  ASSERT_TRUE(CreateDir(temp_path().Append(kPackage0).Append("blabla.dir")));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {});
}

// If the name of the APK does not match com.example.package.name.apk pattern,
// then the package must be deleted.
TEST_F(CacheCleanerTest, ApkNameMismatch) {
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));

  ASSERT_TRUE(apk_cache::DeleteFile(
      temp_path().Append(kPackage0).Append(GetApkFileName(kPackage0))));
  ASSERT_TRUE(CreateFile(
      temp_path().Append(kPackage0).Append(GetApkFileName("blabla"))));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {});
}

// If the name of the main OBB does not match
// main.123.com.example.package.name.obb pattern, then the package must
// be deleted.
TEST_F(CacheCleanerTest, MainObbNameMismatch) {
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));

  ASSERT_TRUE(apk_cache::DeleteFile(temp_path().Append(kPackage0).Append(
      GetMainObbFileName(kPackage0, kObbVersion))));
  ASSERT_TRUE(CreateFile(temp_path().Append(kPackage0).Append(
      GetMainObbFileName("blabla", kObbVersion))));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {});
}

// If the name of the main OBB does not match
// patch.123.com.example.package.name.obb pattern, then the package must
// be deleted.
TEST_F(CacheCleanerTest, PatchObbNameMismatch) {
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));

  ASSERT_TRUE(apk_cache::DeleteFile(temp_path().Append(kPackage0).Append(
      GetPatchObbFileName(kPackage0, kObbVersion))));
  ASSERT_TRUE(CreateFile(temp_path().Append(kPackage0).Append(
      GetPatchObbFileName("blabla", kObbVersion))));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {});
}

// Verify that expired package is deleted.
TEST_F(CacheCleanerTest, Outdated) {
  // Package0 is expired. Should be deleted.
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));
  base::Time atime_0 =
      base::Time::Now() - (kValidityPeriod + base::TimeDelta::FromDays(1));
  WriteAttributes(temp_path().Append(kPackage0), kPackage0, atime_0);

  // Package1 is 1 more day before expire. Should not be deleted.
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage1));
  base::Time atime_1 =
      base::Time::Now() - (kValidityPeriod - base::TimeDelta::FromDays(1));
  WriteAttributes(temp_path().Append(kPackage1), kPackage1, atime_1);

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {kPackage1});
}

// Check that symbolic links are deleted.
TEST_F(CacheCleanerTest, Symlink) {
  base::ScopedTempDir temp_dir_1;
  ASSERT_TRUE(temp_dir_1.CreateUniqueTempDir());

  // Create symlink to a file in the cache root.
  const base::FilePath symlink_file_target_path =
      temp_dir_1.GetPath().Append("symlink-target-file");
  ASSERT_TRUE(CreateFile(symlink_file_target_path));
  ASSERT_TRUE(CreateSymbolicLink(symlink_file_target_path,
                                 temp_path().Append("symlink-file")));

  // Create symlink to the valid package directory in the cache root.
  // We don't follow symlinks and they must be removed from the cache root.
  const base::FilePath symlink_dir_target_path =
      temp_dir_1.GetPath().Append(kPackage0);
  ASSERT_TRUE(CreateValidPackage(temp_dir_1.GetPath(), kPackage0));
  ASSERT_TRUE(CreateSymbolicLink(symlink_dir_target_path,
                                 temp_path().Append(kPackage0)));

  // Create symlink in the package.
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage1));
  ASSERT_TRUE(
      CreateSymbolicLink(symlink_file_target_path,
                         temp_path().Append(kPackage1).Append("symlink")));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {});
  EXPECT_TRUE(base::PathExists(symlink_file_target_path));
  EXPECT_TRUE(base::DirectoryExists(symlink_dir_target_path));
}

// Verify that deletion of the a package or file does not lead to
// the deletion of the valid package.
TEST_F(CacheCleanerTest, Combined) {
  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage0));

  ASSERT_TRUE(CreateValidPackage(temp_path(), kPackage1));
  base::Time atime =
      base::Time::Now() - (kValidityPeriod + base::TimeDelta::FromDays(1));
  WriteAttributes(temp_path().Append(kPackage1), kPackage1, atime);

  ASSERT_TRUE(CreateFile(temp_path().Append("odd.file")));

  EXPECT_TRUE(Clean(temp_path()));

  VerifyCache(temp_path(), {kPackage0});
}

}  // namespace apk_cache
