/**
 * @file Power.h
 * @author Phillip Kühne
 * @brief This component provides utilities for keeping track of power usage
 * consumption.
 * @version 0.1
 * @date 2024-11-23 
 */

#include <queue>
#include <Arduino.h>
#include "Consumptions.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#ifndef Power_h
#define Power_h

#define TOTAL_POWER_MILLIWATTS  POWER_BUDGET

enum TaskResumptionReason {
    POWER_AVAILABLE,
    TIMEOUT
};

class Power {
    protected:
    static const uint16_t totalPowerBudget = TOTAL_POWER_MILLIWATTS;
    uint16_t freePowerBudget;
    std::queue<TaskHandle_t> waitingTasks;
    void checkWaitingTasks(void);
    bool takePowerIfAvailable(uint16_t neededPower);
    static Power* powerInstance;
    Power();

    public:
    static void begin();
    /// @brief Initialize the singleton instance of the power manager
    /// @return reference to the power manager
    static Power *getPowerManager();
    uint16_t getFreePowerBudget(void);
    /// @brief Request an allowance of a certain number of milliwatts from the power scheduler
    /// @param neededPower the amount of power we want to be accounted for (in mW)
    /// @return whether the power could be successfully allocated
    bool tryAccquirePowerAllowance(uint16_t neededPower);
    /// @brief "Return" a certain amount of power when it is no longer needed
    /// @param neededPower the amount of power to return (in mW)
    /// @return whether the power
    void releasePower(uint16_t power);

    /// @brief Wait for a certain amount of power to be available
    /// @param neededPower the amount of power we want to be accounted for (in mW)
    /// @param TicksToWait the amount of time to wait for the power to become available
    /// @return whether the power could be successfully allocatedy
    bool waitForPowerAllowance(uint16_t neededPower,TickType_t TicksToWait);
    /// @brief Put the ESP32 into deep sleep mode, without a method to wake up again. Basically this is a shutdown.
    void beginPermanentDeepSleep(void);
};

#endif //Power