// 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, false /* recursive */);
}

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:
  CacheCleanerTest() { EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); }
  ~CacheCleanerTest() { EXPECT_TRUE(temp_dir_.Delete()); }
  const base::FilePath& temp_path() const { return temp_dir_.GetPath(); }

 private:
  base::ScopedTempDir temp_dir_;
  DISALLOW_COPY_AND_ASSIGN(CacheCleanerTest);
};

// 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(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(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(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(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(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(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(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
