#pragma once

#include <cstddef>
#include <memory>
#include <string>
#include <unordered_map>

#include "core/preview_frame.hpp"

namespace smartcut::core {

class ThumbnailCache {
 public:
  explicit ThumbnailCache(std::size_t capacity) : capacity_(capacity) {}
  std::shared_ptr<PreviewFrame> get(const std::string& source_uuid, const std::string& index_fingerprint,
                                    std::size_t frame_index) const {
    const auto found = entries_.find(key(source_uuid, index_fingerprint, frame_index));
    return found == entries_.end() ? nullptr : found->second;
  }
  bool put(const std::string& source_uuid, const std::string& index_fingerprint,
           std::size_t frame_index, std::shared_ptr<PreviewFrame> frame) {
    if (!frame || source_uuid.empty() || index_fingerprint.empty() || capacity_ == 0) return false;
    const auto entry_key = key(source_uuid, index_fingerprint, frame_index);
    if (entries_.size() >= capacity_ && entries_.find(entry_key) == entries_.end()) entries_.erase(entries_.begin());
    entries_[entry_key] = std::move(frame);
    return true;
  }
  std::size_t size() const { return entries_.size(); }
 private:
  static std::string key(const std::string& source_uuid, const std::string& index_fingerprint,
                         std::size_t frame_index) {
    return source_uuid + ":" + index_fingerprint + ":" + std::to_string(frame_index);
  }
  std::size_t capacity_;
  std::unordered_map<std::string, std::shared_ptr<PreviewFrame>> entries_;
};

}  // namespace smartcut::core
