/*
 * Utils.h
 *
 *  Created on: Feb 19, 2025
 *      Author: Murdock
 */

#ifndef UTILS_H_
#define UTILS_H_

extern unsigned int __heap_start; 	// Start of heap (used by malloc, dynamic allocations)
extern unsigned int *__brkval;		// Current heap end (if NULL, no heap allocations exist)
extern int __data_start;			// Start of .data section (initialized global/static variables)

class Utils {
public:
	Utils();

	/**
	 * Converts a temperature value from Celsius to Fahrenheit.
	 *
	 * @param celsius The temperature in Celsius.
	 * @return The equivalent temperature in Fahrenheit.
	 */
	static float getFahrenheit(float celsius);
	static float mapFloat(float value, float inMin, float inMax, float outMin, float outMax);
	static float getCelsius(int sensorValue);

	/**
	 * @brief Get the total available SRAM size.
	 *
	 * This function calculates the total SRAM available on the microcontroller.
	 *
	 * - `RAMEND` is a built-in macro that defines the last valid RAM address.
	 * - `__data_start` marks the beginning of the SRAM usage.
	 * - The total memory is calculated as the difference plus one.
	 *
	 * @return The total SRAM in bytes.
	 */
	static unsigned int getTotalMemory();

	/**
	 * @brief Get the amount of free SRAM available.
	 *
	 * This function calculates the free RAM available for use by the program.
	 *
	 * - The stack grows downward from RAMEND.
	 * - The heap grows upward from `__heap_start`.
	 * - If `__brkval` is NULL, it means no dynamic allocations have occurred.
	 * - The free memory is the difference between the current stack pointer
	 *   (local variable `freeMemory`) and the heap.
	 *
	 * @return The amount of free SRAM in bytes.
	 */
	static unsigned int getFreeMemory();

	/**
	 * @brief Get the amount of used SRAM.
	 *
	 * This function calculates how much SRAM is currently occupied.
	 *
	 * - It subtracts free memory from the total available SRAM.
	 * - This includes usage by the stack, heap, `.data`, and `.bss` sections.
	 *
	 * @return The amount of used SRAM in bytes.
	 */
	static unsigned int getUsedMemory();

	// Helper function to check if input is stored in Flash memory
	inline static bool isFlashString(const void *ptr) {
		return reinterpret_cast<uint16_t>(ptr) >= 0x100;
	}
};

#endif /* UTILS_H_ */
