#pragma once

#include <array>
#include <cstdint>
#include <utility>

#include "adc.h"
#include "utils.hpp"

class LightSensors {
  public:
    static constexpr auto MAX_VALUE = uint16_t{4095};

    static inline const std::array<uint16_t, 3>& getValues()
    {
        sampleLightSensors();
        return m_adcValues;
    }

    template<size_t Idx>
    static inline const int16_t& getValue()
    {
        static_assert(Idx < m_adcValues.size(), "Invalid light sensor index");

        sampleLightSensors();
        return m_adcValues[Idx];
    }

  private:
    static std::array<uint16_t, 3> m_adcValues;

    static void sampleLightSensors()
    {
        HAL_ADC_Start(&hadc);

        util::for_constexpr(
            [](const auto& idx) {
                constexpr auto i = idx.value;
                HAL_ADC_PollForConversion(&hadc, 1000);
                m_adcValues[i] = HAL_ADC_GetValue(&hadc);
            },
            std::make_index_sequence<m_adcValues.size()>{});

        HAL_ADC_Stop(&hadc);
    }
};
