#include "torlinkc/sources/cache.hpp"

#include <algorithm>
#include <cctype>

namespace torlinkc {

namespace {

constexpr std::chrono::minutes kTtl{5};

std::string trim(const std::string& s) {
  auto first = s.find_first_not_of(" \t\r\n");
  if (first == std::string::npos) return "";
  auto last = s.find_last_not_of(" \t\r\n");
  return s.substr(first, last - first + 1);
}

std::string toLower(std::string s) {
  std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); });
  return s;
}

std::string cacheKey(const std::string& sourceId, const std::string& query) {
  return sourceId + "::" + toLower(trim(query));
}

}  // namespace

std::vector<TorrentResult> SearchCache::cachedSearch(const Source& source, const std::string& query,
                                                       const SearchOptions& opts) {
  const std::string key = cacheKey(source.id, query);
  auto it = cache_.find(key);
  const auto now = std::chrono::steady_clock::now();
  if (it != cache_.end() && now - it->second.at < kTtl) return it->second.results;

  std::vector<TorrentResult> results = source.search(query, opts);
  cache_[key] = Entry{now, results};
  return results;
}

}  // namespace torlinkc
