// 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 <fnmatch.h>

#include <memory>
#include <string>
#include <unordered_set>
#include <vector>

#include <base/files/file.h>
#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/json/json_reader.h>
#include <base/logging.h>
#include <base/time/time.h>
#include <base/values.h>

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

namespace apk_cache {

constexpr char kAttrJson[] = "attr.json";
constexpr char kApkExtension[] = ".apk";
constexpr char kObbExtension[] = ".obb";
constexpr char kMainObbPrefix[] = "main.";
constexpr char kPatchObbPrefix[] = "patch.";

namespace {

constexpr char kKeyAttributesAtime[] = "attributes.atime";

// Removes all the files (if any) from cache root. Does not remove
// directories. Returns true if all the intended files were deleted.
bool RemoveUnexpectedFilesFromCacheRoot(const base::FilePath& cache_root) {
  std::unordered_set<std::string> database_files(
      kDatabaseFiles, kDatabaseFiles + kDatabaseFilesCount);
  return RemoveUnexpectedItemsFromDir(
      cache_root,
      base::FileEnumerator::FileType::FILES |
          base::FileEnumerator::FileType::SHOW_SYM_LINKS,
      database_files);
}

// Returns if |file_name| matches the |pattern|.
bool IsMatch(const std::string& file_name, const std::string& pattern) {
  return fnmatch(pattern.c_str(), file_name.c_str(), FNM_NOESCAPE) == 0;
}

// Parses contents of the attributes JSON file and verifies that last access
// time of the package was at most 30 days ago.
bool IsAccessTimeValid(const base::StringPiece& json_message) {
  auto root = base::JSONReader::ReadAndReturnValueWithError(
      json_message, base::JSON_PARSE_RFC);
  if (!root.value) {
    LOG(ERROR) << "Reading attributes JSON failed (error message: "
               << root.error_message << ").";
    return false;
  }

  if (!root.value->is_dict()) {
    LOG(ERROR) << "Could not interpret the JSON as a dictionary.";
    return false;
  }

  const std::string* atime_str =
      root.value->FindStringPath(kKeyAttributesAtime);
  if (!atime_str) {
    LOG(ERROR) << "Could not read the value of the access time with the "
               << kKeyAttributesAtime << " key.";
    return false;
  }

  base::Time atime;
  if (!base::Time::FromString(atime_str->c_str(), &atime)) {
    LOG(ERROR) << "Can not parse the date: " << *atime_str;
    return false;
  }

  const base::TimeDelta age = base::Time::Now() - atime;
  return age < kValidityPeriod;
}

// Verifies that package directory contains all the necessary files, does
// not contain any extra files/directories and was accessed within last 30 days.
// Returns true if the package is valid and should be kept in the cache.
bool IsPackageValid(const base::FilePath& package_path) {
  // Package directory must contain:
  // 1. One .apk file
  // 2. One attr.json file
  // 3. No or one main .obb file.
  // 4. No or one patch .obb file.
  // 5. No other files or directories.
  base::FileEnumerator files(package_path, false /* recursive */,
                             base::FileEnumerator::DIRECTORIES |
                                 base::FileEnumerator::FILES |
                                 base::FileEnumerator::SHOW_SYM_LINKS);
  int apk_count = 0;
  int attr_count = 0;
  int main_obb_count = 0;
  int patch_obb_count = 0;

  const std::string package_name = package_path.BaseName().value();
  const std::string apk_file_name = package_name + kApkExtension;
  const std::string main_obb_file_name =
      std::string(kMainObbPrefix) + "*" + package_name + kObbExtension;
  const std::string patch_obb_file_name =
      std::string(kPatchObbPrefix) + "*" + package_name + kObbExtension;

  for (base::FilePath file_path = files.Next(); !file_path.empty();
       file_path = files.Next()) {
    if (base::DirectoryExists(file_path)) {
      LOG(INFO) << "There are directories in " << package_path.value();
      return false;
    }

    const std::string file_name = file_path.BaseName().value();
    if (IsMatch(file_name, apk_file_name)) {
      apk_count++;
    } else if (IsMatch(file_name, kAttrJson)) {
      attr_count++;
    } else if (IsMatch(file_name, main_obb_file_name)) {
      main_obb_count++;
    } else if (IsMatch(file_name, patch_obb_file_name)) {
      patch_obb_count++;
    } else {
      LOG(INFO) << package_name << " contains unnecessary files.";
      return false;
    }
  }

  if (apk_count != 1) {
    LOG(INFO) << "Number of APK files is not equal to 1 in " << package_name;
    return false;
  }

  if (attr_count != 1) {
    LOG(INFO) << "Number of JSON attributes files is " << attr_count
              << " which not equal to 1 in " << package_name;
    return false;
  }

  if (main_obb_count > 1) {
    LOG(INFO) << "Number of patch OBB files is " << main_obb_count
              << ", which greater then 1 in " << package_name;
    return false;
  }

  if (patch_obb_count > 1) {
    LOG(INFO) << "Number of patch OBB files is " << patch_obb_count
              << ", which greater then 1 in " << package_name;
    return false;
  }

  const base::FilePath attr_file_path = package_path.Append(kAttrJson);
  std::string attr_json_contents;
  if (!base::ReadFileToString(attr_file_path, &attr_json_contents)) {
    LOG(ERROR) << "Could not read the attributes file.";
    return false;
  }

  return IsAccessTimeValid(attr_json_contents);
}

}  // namespace

bool Clean(const base::FilePath& cache_path) {
  if (!base::DirectoryExists(cache_path)) {
    LOG(ERROR) << "APK cache directory " << cache_path.value()
               << " does not exist";
    return false;
  }

  bool success = RemoveUnexpectedFilesFromCacheRoot(cache_path);

  base::FileEnumerator packages(
      cache_path, false /* recursive */,
      base::FileEnumerator::DIRECTORIES | base::FileEnumerator::SHOW_SYM_LINKS);

  for (base::FilePath package_path = packages.Next(); !package_path.empty();
       package_path = packages.Next()) {
    // Skip |files| directory which should be managed by database cleaner.
    if (package_path.BaseName().MaybeAsASCII() == std::string(kFilesBase))
      continue;

    if (!IsPackageValid(package_path)) {
      if (!base::DeletePathRecursively(package_path)) {
        LOG(ERROR) << "Error deletion path " << package_path.value();
        success = false;
      }
    } else {
      LOG(INFO) << "Package " << package_path.value() << " looks OK.";
    }
  }

  return success;
}

}  // namespace apk_cache
