// Copyright 2020 The Fuchsia 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 "src/developer/debug/zxdb/common/cache_dir.h"

#include <fcntl.h>
#include <sys/stat.h>

#include <algorithm>
#include <filesystem>
#include <system_error>
#include <tuple>
#include <utility>
#include <vector>

#include "lib/syslog/cpp/macros.h"
#include "src/developer/debug/zxdb/common/file_util.h"

#if defined(__APPLE__)
#define st_atim st_atimespec
#endif

namespace zxdb {

namespace {

uint64_t TsToNs(const timespec& ts) { return ts.tv_sec * 1000000000 + ts.tv_nsec; }

}  // namespace

CacheDir::CacheDir(std::filesystem::path dir, uint64_t max_size_bytes)
    : cache_dir_(std::move(dir)), max_size_(max_size_bytes) {
  for (const auto& p : std::filesystem::recursive_directory_iterator(cache_dir_)) {
    std::error_code err;
    if (p.is_regular_file(err)) {
      struct stat file_stat;
      if (!lstat(p.path().c_str(), &file_stat)) {
        file_info_[p.path()].atime = TsToNs(file_stat.st_atim);
        file_info_[p.path()].size = file_stat.st_size;
        total_size_ += file_stat.st_size;
      }
    }
  }

  PruneDir();
}

void CacheDir::NotifyFileAccess(const std::filesystem::path& file) {
  if (!PathStartsWith(file, cache_dir_))
    return;

  if (auto exist = file_info_.find(file); exist != file_info_.end()) {
    timespec now;
    clock_gettime(CLOCK_REALTIME, &now);

    // Only touch the access time.
    timespec ts[2] = {now, {0, UTIME_OMIT}};
    utimensat(AT_FDCWD, file.c_str(), ts, 0);
    exist->second.atime = TsToNs(now);
  } else {
    struct stat file_stat;

    if (!lstat(file.c_str(), &file_stat)) {
      file_info_[file].atime = TsToNs(file_stat.st_atim);
      file_info_[file].size = file_stat.st_size;
      total_size_ += file_stat.st_size;

      PruneDir();
    }
  }
}

void CacheDir::PruneDir() {
  if (total_size_ <= max_size_)
    return;

  std::vector<std::pair<std::string, FileInfo>> file_info_v(file_info_.begin(), file_info_.end());
  std::sort(file_info_v.begin(), file_info_v.end(),
            [](auto x, auto y) { return x.second.atime < y.second.atime; });

  // Never remove the last file, regardless of how big it is.
  file_info_v.pop_back();

  for (const auto& [file, info] : file_info_v) {
    std::error_code err;
    std::filesystem::remove(file, err);
    file_info_.erase(file);
    total_size_ -= info.size;

    if (total_size_ <= max_size_)
      break;
  }
}

}  // namespace zxdb
