#ifndef MINORI_CORE_FILESYSTEM_H_
#define MINORI_CORE_FILESYSTEM_H_
#include <filesystem>
#include <functional>
#include <string>
#include <unordered_map>

namespace Filesystem {

void CreateDirectories(const std::filesystem::path &path);
std::filesystem::path GetDotPath();    // %APPDATA%/minori/, ~/Library/Application Support/minori/, ~/.config/minori/...
std::filesystem::path GetConfigPath(); // (dotpath)/config.json
std::filesystem::path GetAnimeDBPath();      // (dotpath)/anime/db.json
std::filesystem::path GetTorrentsPath();     // (dotpath)/torrents/...
std::filesystem::path GetAnimePostersPath(); // (dotpath)/anime/posters/

struct PathHash {
	auto operator()(const std::filesystem::path &p) const noexcept {
		return std::filesystem::hash_value(p);
	}
};

template<typename T>
using PathMap = std::unordered_map<std::filesystem::path, T, PathHash>;

/* ------------------------------------------------------------------------ */
/* Filesystem watcher interface. This is implemented differently on
 * different platforms :) */

struct IWatcher {
	enum Event {
		/* File/directory 'path' was created */
		Created,
		/* File/directory 'path' was deleted */
		Deleted,
	};

	using EventHandler = std::function<void(void *opaque, const std::filesystem::path &path, Event event)>;

	virtual ~IWatcher() = default;
	virtual void Process() = 0;
};

/* Constructor functions. Yes, I'm doing this the C way :) */
IWatcher *GetRecursiveFilesystemWatcher(void *opaque, const std::filesystem::path &path,
                                        IWatcher::EventHandler handler);
IWatcher *GetFilesystemWatcher(void *opaque, const std::filesystem::path &path, IWatcher::EventHandler handler);

} // namespace Filesystem

#endif // MINORI_CORE_FILESYSTEM_H_
