/*
 * Copyright © 2026 Pierrick Caillon <pierrick.caillon+zipdirfs@megami.fr>
 */
#include "ZipDirFs/Utilities/FileTime.h"

namespace ZipDirFs::Utilities
{
	namespace fs = std::filesystem;

	static auto clock_anchor()
	{
		using namespace std::chrono;
		static const auto anchor = []
		{
			while (true)
			{
				const auto sysBefore = system_clock::now();
				const auto fsRawNow = fs::file_time_type::clock::now();
				const auto sysAfter = system_clock::now();

				const auto sysBeforeRoundedSeconds = floor<seconds>(sysBefore);
				const auto sysAfterRoundedSeconds = floor<seconds>(sysAfter);
				const auto fsRoundedSeconds = floor<seconds>(fsRawNow);

				if (sysBeforeRoundedSeconds == sysAfterRoundedSeconds)
				{
					return std::pair{
						fs::file_time_type{fsRoundedSeconds.time_since_epoch()},
						system_clock::time_point{sysBeforeRoundedSeconds.time_since_epoch()}};
				}
			}
		}();
		return anchor;
	}

	static std::time_t to_time_t(const fs::file_time_type& value)
	{
		using namespace std::chrono;
		auto [fsNow, sysNow] = clock_anchor();
		const auto sctp = time_point_cast<system_clock::duration>(value - fsNow + sysNow);
		return system_clock::to_time_t(sctp);
	}

	FileTime::FileTime() : time(0) {}
	FileTime::FileTime(fs::file_time_type value) : time(to_time_t(value)) {}
	FileTime::FileTime(std::time_t value) : time(value) {}
} // namespace ZipDirFs::Utilities
