#include <string>
#include <vector>

#include "animia.h"
#include "animia/strategies.h"
#include "animia/types.h"

#ifdef ANIMIA_ON_WIN32
#	include "animia/fd/win32.h"
#elif defined(ANIMIA_ON_LINUX)
#	include "animia/fd/linux.h"
#elif defined(ANIMIA_ON_UNIX)
#	include "animia/fd/bsd.h"
#endif

namespace animia::internal {

/* really stupid hack to get fd to point to the right
   thing */
#ifdef ANIMIA_ON_WIN32
win32::Win32FdTools os_fd;
#elif defined(ANIMIA_ON_LINUX)
linux::LinuxFdTools os_fd;
#elif defined(ANIMIA_ON_UNIX)
unix::UnixFdTools os_fd;
#else
BaseFdTools os_fd;
#endif

BaseFdTools& fd = os_fd;

}

namespace animia {

static bool ProcessInPlayers(const std::vector<Player>& players, const std::string& name, Player& player_) {
	for (const auto& player : players) {
		for (const auto& exe : player.executables) {
			if (exe == name.substr(0, name.rfind(".exe"))) {
				player_ = player;
				return true;
			}
		}
	}
	return false;
}

bool GetResults(const std::vector<Player>& players, std::vector<Result>& results) {
	std::set<internal::pid_t> pids;

	if (!internal::fd.GetAllPids(pids))
		return false;

	for (const auto& pid : pids) {
		std::string name;
		internal::fd.GetProcessName(pid, name);

		Player player;
		if (!ProcessInPlayers(players, name, player))
			continue;

		Result result;
		result.process.pid = pid;
		result.process.name = name;
		result.player = player;
		results.push_back(result);
	}

	return internal::ApplyStrategies(results);
}

}
