#ifdef WIN32
#	include <shlobj.h>
#elif defined(MACOSX)
#	include "sys/osx/filesystem.h"
#elif defined(__linux__)
#	include <pwd.h>
#	include <sys/types.h>
#endif

#ifdef WIN32
#	define DELIM "\\"
#else
#	define DELIM "/"
#	include <errno.h>
#	include <unistd.h>
#	include <sys/stat.h>
#endif

#include "core/filesystem.h"
#include "core/config.h"
#include "core/strings.h"
#include <filesystem>
#include <limits.h>

namespace Filesystem {

/* this runs fs::create_directories() on the
   PARENT directory. */
void CreateDirectories(const std::filesystem::path& path) {
	std::filesystem::create_directories(path.parent_path());
}

std::filesystem::path GetDotPath() {
#ifdef WIN32
	std::filesystem::path path;
	wchar_t* buf;
	if (SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_CREATE, NULL, &buf) == S_OK)
		path = buf;
	else
		return std::filesystem::path();
	CoTaskMemFree(buf);
	return path / CONFIG_DIR;
#elif defined(MACOSX)
	return std::filesystem::path(osx::GetApplicationSupportDirectory()) / CONFIG_DIR;
#else // just assume POSIX
	const char* home = getenv("HOME");
	if (home != NULL)
		path = home;
#	ifdef __linux__
	else
		path = getpwuid(getuid())->pw_dir;
#	endif // __linux__
	if (!path.empty())
		return path / ".config";
	else
		return std::filesystem::path();
#endif     // !WIN32 && !MACOSX
}

std::filesystem::path GetConfigPath() {
	return GetDotPath() / CONFIG_NAME;
}

std::filesystem::path GetPlayersPath() {
	return GetDotPath() / "recognition" / "players.json";
}

std::filesystem::path GetExtensionsPath() {
	return GetDotPath() / "recognition" / "extensions.json";
}

std::filesystem::path GetAnimeDBPath() {
	return GetDotPath() / "anime" / "db.json";
}

} // namespace Filesystem
