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