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

namespace apk_cache {

const char kAttrJson[] = "attr.json";
const char kApkExtension[] = ".apk";
const char kObbExtension[] = ".obb";
const char kMainObbPrefix[] = "main.";
const char kPatchObbPrefix[] = "patch.";
const base::TimeDelta kValidityPeriod = base::TimeDelta::FromDays(30);

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) {
  bool success = true;
  base::FileEnumerator unexpected_files(
      cache_root, false /* recursive */,
      base::FileEnumerator::FILES | base::FileEnumerator::SHOW_SYM_LINKS);

  for (base::FilePath unexpected_file_path = unexpected_files.Next();
       !unexpected_file_path.empty();
       unexpected_file_path = unexpected_files.Next()) {
    LOG(INFO) << "Deleting file " << unexpected_file_path.value();
    if (!base::DeleteFile(unexpected_file_path, false /* recursive */)) {
      LOG(ERROR) << "Could not delete file " << unexpected_file_path.value();
      success = false;
    }
  }

  return success;
}

// Returns if |file_name| matches the |pattern|.
bool IsMatch(const base::FilePath::StringType& file_name,
             const base::FilePath::StringType& 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) {
  std::string error_msg;
  int error_code = 0;
  const std::unique_ptr<base::Value> root(base::JSONReader::ReadAndReturnError(
      json_message, base::JSON_PARSE_RFC, &error_code, &error_msg));
  if (!root.get()) {
    LOG(ERROR) << "Reading attributes JSON failed (error code: " << error_code
               << "; error message: " << error_msg << ").";
    return false;
  }

  base::DictionaryValue* root_dict = nullptr;
  if (!root->GetAsDictionary(&root_dict)) {
    LOG(ERROR) << "Could not interpret the JSON as a dictionary.";
    return false;
  }

  std::string atime_str;
  if (!root_dict->GetString(kKeyAttributesAtime, &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 base::FilePath::StringType 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()) {
    if (!IsPackageValid(package_path)) {
      if (!base::DeleteFile(package_path, true /* recursive */)) {
        LOG(ERROR) << "Error deletion path " << package_path.value();
        success = false;
      }
    } else {
      LOG(INFO) << "Package " << package_path.value() << " looks OK.";
    }
  }

  return success;
}

}  // namespace apk_cache
