#include "core/time.h"
#include <cassert>
#include <cmath>
#include <cstdint>
#include <ctime>
#include <string>

namespace Time {

Duration::Duration(int64_t l) {
	length = l;
}

std::string Duration::AsRelativeString() {
	std::string result;

	auto get = [](int64_t val, const std::string& s, const std::string& p) {
		return std::to_string(val) + " " + (val == 1 ? s : p);
	};

	if (InSeconds() < 60)
		result = get(InSeconds(), "second", "seconds");
	else if (InMinutes() < 60)
		result = get(InMinutes(), "minute", "minutes");
	else if (InHours() < 24)
		result = get(InHours(), "hour", "hours");
	else if (InDays() < 28)
		result = get(InDays(), "day", "days");
	else if (InDays() < 365)
		result = get(InDays() / 30, "month", "months");
	else
		result = get(InDays() / 365, "year", "years");

	if (length < 0)
		result = "In " + result;
	else
		result += " ago";

	return result;
}

int64_t Duration::InSeconds() {
	return length;
}

int64_t Duration::InMinutes() {
	return std::llround((double)length / 60.0);
}

int64_t Duration::InHours() {
	return std::llround((double)length / 3600.0);
}

int64_t Duration::InDays() {
	return std::llround((double)length / 86400.0);
}

int64_t GetSystemTime() {
	assert(sizeof(int64_t) >= sizeof(time_t));
	time_t t = std::time(nullptr);
	return *reinterpret_cast<int64_t*>(&t);
}

} // namespace Time