
#pragma warning(disable:4996)

#include "SensorHandler.h"
#include <sstream>
#include <string>
#include <stdio.h>
#include <thread>
#include <list>
#include <time.h>
#include <iomanip>

#ifdef __linux__
     #include <unistd.h>
#elif _WIN32
     #include <windows.h>
#endif

const std::string version = "4.0";

#define TEMP_RAW_FILE     "/sys/bus/platform/drivers/xadc/f8007100.adc/iio\:device0/in_temp0_raw"
#define TEMP_OFFSET_FILE  "/sys/bus/platform/drivers/xadc/f8007100.adc/iio\:device0/in_temp0_offset"
#define TEMP_SCALE_FILE   "/sys/bus/platform/drivers/xadc/f8007100.adc/iio\:device0/in_temp0_scale"

bool bSecureProviderInterface = false; //Enables HTTPS interface on the application service (with token enabled)
bool bSecureArrowheadInterface = false; //Enables HTTPS interface towards ServiceRegistry AH module

inline void parseArguments(int argc, char* argv[]){
     for(int i=1; i<argc; ++i){
          if(strstr("--secureArrowheadInterface", argv[i]))
               bSecureArrowheadInterface = true;
          else if(strstr("--secureProviderInterface", argv[i]))
               bSecureProviderInterface = true;
     }
}

int main(int argc, char* argv[]){

	printf("\n=============================\nProvider Example - v%s\n=============================\n", version.c_str());

     parseArguments(argc, argv);

	SensorHandler oSensorHandler;

//SenML format
//todo:
//generate own measured value into "measuredValue"
//"value" should be periodically updated
//"sLinuxEpoch" should be periodically updated

     std::string measuredValue; //JSON - SENML format
     time_t linuxEpochTime = std::time(0);
     std::string sLinuxEpoch = std::to_string((uint64_t)linuxEpochTime);

    FILE *f_t_raw, *f_t_off, *f_t_scale;
     
    if ( (f_t_raw = fopen(TEMP_RAW_FILE, "r")) == NULL ) {
        printf("Cannot open file %s \n", TEMP_RAW_FILE);
        return -1;
    }

    if ( (f_t_off = fopen(TEMP_OFFSET_FILE, "r")) == NULL ) {
        printf("Cannot open file %s \n", TEMP_OFFSET_FILE);
        return -1;
    }

    if ( (f_t_scale = fopen(TEMP_SCALE_FILE, "r")) == NULL ) {
        printf("Cannot open file %s \n", TEMP_SCALE_FILE);
        return -1;
    }
    printf("OK\n");

    int   t_raw;
    int   t_off;
    float t_scale;

    fscanf(f_t_raw, "%d", &t_raw);
    fscanf(f_t_off, "%d", &t_off);
    fscanf(f_t_scale, "%f", &t_scale);

    if ( fclose(f_t_raw) == EOF ) {
        printf("Cannot close file %s \n", TEMP_RAW_FILE);
        return -1;
    }
    printf("OK\n");

    if ( fclose(f_t_off) == EOF ) {
        printf("Cannot close file %s \n", TEMP_OFFSET_FILE);
        return -1;
    }

    if ( fclose(f_t_scale) == EOF ) {
        printf("Cannot close file %s \n", TEMP_SCALE_FILE);
        return -1;
    }

        
//      double value = 26.0;

    // (raw + offset) * scale ... in milidegree Celsius
    float value = ((float)(t_raw + t_off) * t_scale) / 1000.00f;

//convert double to string
     std::ostringstream streamObj;
     streamObj << std::fixed;
     streamObj << std::setprecision(1);
     streamObj << value;
     std::string sValue = streamObj.str();

     measuredValue =
          "{"
               "\"e\":[{"
                    "\"n\": \"this_is_the_sensor_id\","
                    "\"v\":" + sValue +","
                    "\"t\": \"" + sLinuxEpoch + "\""
                    "}],"
               "\"bn\": \"this_is_the_sensor_id\","
               "\"bu\": \"Celsius\""
          "}";

//do not modify below this

    oSensorHandler.processProvider(measuredValue, bSecureProviderInterface, bSecureArrowheadInterface);

    while (true) {

        linuxEpochTime = std::time(0);
        sLinuxEpoch = std::to_string((uint64_t)linuxEpochTime);

//         if (value < 30.0) value += 0.1;
//         else              value = 26.0;

        if ( (f_t_raw = fopen(TEMP_RAW_FILE, "r")) == NULL ) {
            printf("Cannot open file %s \n", TEMP_RAW_FILE);
            return -1;
        }

        fscanf(f_t_raw, "%d", &t_raw);

        if ( fclose(f_t_raw) == EOF ) {
            printf("Cannot close file %s \n", TEMP_RAW_FILE);
            return -1;
        }

        value = ((float)(t_raw + t_off) * t_scale) / 1000.00f;        
        printf("Zynq Temp : %f °C\n", value);
        
        streamObj.clear();
        streamObj.str("");
        streamObj << std::fixed;
        streamObj << std::setprecision(1);
        streamObj << value;
        sValue = streamObj.str();

        measuredValue =
              "{"
                   "\"e\":[{"
                        "\"n\": \"this_is_the_sensor_id\","
                        "\"v\":" + sValue +","
                        "\"t\": \"" + sLinuxEpoch + "\""
                        "}],"
                   "\"bn\": \"this_is_the_sensor_id\","
                   "\"bu\": \"Celsius\""
              "}";
        
        oSensorHandler.processProvider(measuredValue, bSecureProviderInterface, bSecureArrowheadInterface);

        #ifdef __linux__
            sleep(1);
        #elif _WIN32
            Sleep(1000);
        #endif
	}

    printf("Close file %s ... ", TEMP_RAW_FILE);
    if ( fclose(f_t_raw) == EOF ) {
        printf("FAILED\n");
        return -1;
    }
    printf("OK\n");

	
	return 0;
}

