#pragma once

/**
 * \file Format.h
 * \brief This file contains the definition of the `Format` function.
 */

#include <memory>
#include <stdexcept>
#include <string>

namespace blitz {
namespace utils {

/**
 * \brief Formats a string using a format string and variadic arguments.
 *
 * This function takes a format string and a variable number of arguments and returns a formatted string.
 * The format string can contain placeholders that will be replaced by the corresponding arguments.
 *
 * \param format The format string.
 * \param args The variadic arguments to be formatted.
 * \return The formatted string.
 * \throws std::runtime_error if an error occurs during formatting.
 */
template <typename... Args>
std::string Format(const std::string& format, Args... args) {
	int size = snprintf(nullptr, 0, format.c_str(), args...) + 1;  // Extra space for '\0'
	if (size <= 0) {
		throw std::runtime_error("Error during formatting.");
	}
	std::unique_ptr<char[]> buf(new char[size]);
	snprintf(buf.get(), static_cast<std::size_t>(size), format.c_str(), args...);
	return std::string(buf.get(), buf.get() + size - 1);  // We don't want the '\0' inside
}

}  // namespace utils
}  // namespace blitz
