#include "LibSensors.h"

#ifdef HAVE_SENSORS_SENSORS_H

#include <dlfcn.h>
#include <errno.h>
#include <limits.h>
#include <sensors/sensors.h>

#include "XUtils.h"


static int (*sym_sensors_init)(FILE*);
static void (*sym_sensors_cleanup)(void);
static const sensors_chip_name* (*sym_sensors_get_detected_chips)(const sensors_chip_name*, int*);
static int (*sym_sensors_snprintf_chip_name)(char*, size_t, const sensors_chip_name*);
static const sensors_feature* (*sym_sensors_get_features)(const sensors_chip_name*, int*);
static const sensors_subfeature* (*sym_sensors_get_subfeature)(const sensors_chip_name*, const sensors_feature*, sensors_subfeature_type);
static int (*sym_sensors_get_value)(const sensors_chip_name*, int, double*);

static void* dlopenHandle = NULL;

int LibSensors_init(FILE* input) {
   if (!dlopenHandle) {
      dlopenHandle = dlopen("libsensors.so", RTLD_LAZY);
      if (!dlopenHandle)
         goto dlfailure;

      /* Clear any errors */
      dlerror();

      #define resolve(symbolname) do {                                      \
         *(void **)(&sym_##symbolname) = dlsym(dlopenHandle, #symbolname);  \
         if (!sym_##symbolname || dlerror() != NULL)                        \
            goto dlfailure;                                                 \
      } while(0)

      resolve(sensors_init);
      resolve(sensors_cleanup);
      resolve(sensors_get_detected_chips);
      resolve(sensors_snprintf_chip_name);
      resolve(sensors_get_features);
      resolve(sensors_get_subfeature);
      resolve(sensors_get_value);

      #undef resolve
   }

   return sym_sensors_init(input);

dlfailure:
   if (dlopenHandle) {
      dlclose(dlopenHandle);
      dlopenHandle = NULL;
   }
   return -1;
}

void LibSensors_cleanup(void) {
   if (dlopenHandle) {
      sym_sensors_cleanup();

      dlclose(dlopenHandle);
      dlopenHandle = NULL;
   }
}

int LibSensors_getCPUTemperatures(CPUData* cpus, int cpuCount) {
   if (!dlopenHandle)
      return -ENOTSUP;

   int tempCount = 0;

   int n = 0;
   for (const sensors_chip_name *chip = sym_sensors_get_detected_chips(NULL, &n); chip; chip = sym_sensors_get_detected_chips(NULL, &n)) {
      char buffer[32];
      sym_sensors_snprintf_chip_name(buffer, sizeof(buffer), chip);
      if (!String_startsWith(buffer, "coretemp") && !String_startsWith(buffer, "cpu_thermal"))
         continue;

      int m = 0;
      for (const sensors_feature *feature = sym_sensors_get_features(chip, &m); feature; feature = sym_sensors_get_features(chip, &m)) {
         if (feature->type != SENSORS_FEATURE_TEMP)
            continue;

         if (feature->number > cpuCount)
            continue;

         const sensors_subfeature *sub_feature = sym_sensors_get_subfeature(chip, feature, SENSORS_SUBFEATURE_TEMP_INPUT);
         if (sub_feature) {
            double temp;
            int r = sym_sensors_get_value(chip, sub_feature->number, &temp);
            if (r != 0)
               continue;

            cpus[feature->number].temperature = temp;
            tempCount++;
         }
      }
   }

   return tempCount;
}

#endif /* HAVE_SENSORS_SENSORS_H */
