#include "DR26.hpp"
#include "../../client_satellite/.pio/libdeps/esp32dev/ADS1115_WE/src/ADS1115_WE.h"

static const char *TAG = "DR26";

void DR26::setup() {
    if (sensorConnected) {
        ESP_LOGD(TAG, "ADS already initialized");
        return;
    }
    if (Wire.begin(SDA_PIN, SCL_PIN)) {
        ESP_LOGD(TAG, "Wire initialized");
    } else {
        ESP_LOGE(TAG, "Wire failed to initialize");
    }

    if (ads.init()) {
        ads.setVoltageRange_mV(voltageRange);
        ads.setMeasureMode(ADS1115_SINGLE);
        ESP_LOGD(TAG, "ADS initialized");
        sensorConnected = true;
    } else {
        ESP_LOGE(TAG, "failed to initialize ADS");
        sensorConnected = false;
    }
}

float DR26::readChannel(ADS1115_MUX compareChannel) {
    float voltage = 0.0;
    ads.setCompareChannels(compareChannel);
    ads.startSingleMeasurement();
    while (ads.isBusy()) {
    }
    voltage = ads.getResult_V(); // alternative: getResult_mV for Millivolt
    return voltage;
}

Measurement DR26::readData() {
    float volts = 0;
    int16_t adc = 0;

    if (!sensorConnected) {
        return {ERROR_VALUE, static_cast<uint8_t>(channel), NO_I2C_ADDRESS, MeasurementType::CIRCUMFERENCE_INCREMENT,
                ErrorType::SENSOR_INIT_FAILED};
    }

    volts = readChannel(channel);

    return {volts, static_cast<uint8_t>(channel), NO_I2C_ADDRESS, MeasurementType::CIRCUMFERENCE_INCREMENT,
            ErrorType::DATA_OK};
}

void DR26::setVoltageRange(ADS1115_RANGE newVoltageRange) {
    ads.setVoltageRange_mV(newVoltageRange);
}

void DR26::setChannel(ADS1115_MUX newChannel) {
    channel = newChannel;
}

std::list<Message> DR26::buildMessages() {
    std::list<Message> messages;
    auto data = readData();
    auto time = Time::getInstance().getEpochSeconds();
    messages.emplace_back(data, sensorInformation, time);
    return messages;
}

SensorInformation DR26::getSensorInformation() const {
    return sensorInformation;
}

DR26::DR26(ADS1115_MUX channel, ADS1115_RANGE voltageRange) : channel(channel), voltageRange(voltageRange) {
    ads = ADS1115_WE(0x48);
}
DR26::DR26(ADS1115_MUX channel, ADS1115_RANGE voltageRange, uint8_t address)
    : channel(channel), voltageRange(voltageRange) {
    ads = ADS1115_WE(address);
}