/*
 * @Author: DI JUNKUN
 * @Date: 2024-11-07
 * Copyright (c) 2024 by DI JUNKUN, All Rights Reserved.
 */

#ifndef _THUMBNAIL_H_
#define _THUMBNAIL_H_

#include <cstring>
#include <filesystem>
#include <map>
#include <unordered_map>
#include <vector>

namespace crossdesk {

class Thumbnail {
 public:
  struct RecentConnection {
    std::filesystem::path image_path;
    std::string remote_id;
    std::string remote_host_name;
    std::string password;
    bool remember_password = false;
  };

 public:
  Thumbnail(std::string save_path);
  explicit Thumbnail(std::string save_path, unsigned char* aes128_key,
                     unsigned char* aes128_iv);
  ~Thumbnail();

 public:
  int SetThumbnailDpiScale(float dpi_scale);

  int SaveToThumbnail(const char* yuv420p, int width, int height,
                      const std::string& remote_id,
                      const std::string& host_name,
                      const std::string& password);

  int LoadThumbnail(
      std::vector<std::pair<std::string, Thumbnail::RecentConnection>>&
          recent_connections,
      int* width, int* height);

  bool DecodeImage(const std::filesystem::path& image_path,
                   std::vector<unsigned char>* rgba, int* width,
                   int* height) const;

  int DeleteThumbnail(const std::string& filename_keyword);

  int DeleteAllFilesInDirectory();

  int GetKey(unsigned char* aes128_key) {
    std::memcpy(aes128_key, aes128_key_, sizeof(aes128_key_));
    return sizeof(aes128_key_);
  }

  int GetIv(unsigned char* aes128_iv) {
    std::memcpy(aes128_iv, aes128_iv_, sizeof(aes128_iv_));
    return sizeof(aes128_iv_);
  }

  int GetKeyAndIv(unsigned char* aes128_key, unsigned char* aes128_iv) {
    std::memcpy(aes128_key, aes128_key_, sizeof(aes128_key_));
    std::memcpy(aes128_iv, aes128_iv_, sizeof(aes128_iv_));
    return 0;
  }

 private:
  std::vector<std::filesystem::path> FindThumbnailPath(
      const std::filesystem::path& directory);

  std::string AES_encrypt(const std::string& plaintext, unsigned char* key,
                          unsigned char* iv);

  std::string AES_decrypt(const std::string& ciphertext, unsigned char* key,
                          unsigned char* iv);

 private:
  int thumbnail_width_ = 160;
  int thumbnail_height_ = 90;
  char* rgba_buffer_ = nullptr;
  std::string save_path_ = "thumbnails/";

  unsigned char aes128_key_[16];
  unsigned char aes128_iv_[16];
  unsigned char ciphertext_[64];
  unsigned char decryptedtext_[64];
};
}  // namespace crossdesk
#endif
