#include <zephyr.h>
#include <device.h>
#include <devicetree.h>
#include <drivers/sensor.h>
#include <logging/log.h>

LOG_MODULE_REGISTER(MAIN_SPS30, CONFIG_SENSOR_LOG_LEVEL);

static const struct device *get_sps30_device(void)
{
	const struct device *dev = device_get_binding( DT_LABEL(DT_INST(0, sensirion_sps30)) );
	if (dev == NULL) {
		/* No such node, or the node does not have status "okay". */
		printk("\nError: no device found.\n");
		return NULL;
	}

	if (!device_is_ready(dev)) {
		printk("\nError: Device \"%s\" is not ready; "
		       "check the driver initialization logs for errors.\n",
		       dev->name);
		return NULL;
	}

	printk("Found device \"%s\", getting sensor data\n", dev->name);
	return dev;
}

void main(void)
{
        uint8_t i = 0;
	int ret = 0;
        const struct device *dev = get_sps30_device();

	if (dev == NULL) {
		return;
	}
        
        struct sensor_value pm1,pm_2_5, pm_4, pm_10, attr_meas_time, attr_samples_num, manual_fan_cleaning_ms;
        struct sensor_value fan, speed, laser;
        struct sensor_value clean_interval_s_read,attr_meas_time_read;

        static uint16_t test_count = 0;
        while (1) {
                LOG_INF("------ TEST #%d\n",++test_count);
                attr_meas_time.val1 = 5;
                attr_samples_num.val1 = 5;
                sensor_attr_set(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_DURATION_TIME_S,&attr_meas_time);
                sensor_attr_set(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_SAMPLES,&attr_samples_num);
                sensor_attr_get(dev,0,SENSOR_ATTR_AIR_QUALITY_FAN_CLEAN_INTERVAL,&clean_interval_s_read);
                LOG_INF("Fan clean interval: %d",clean_interval_s_read.val1);

                sensor_attr_get(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_DURATION_TIME_S,&attr_meas_time_read);
                sensor_attr_get(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_SAMPLES,&attr_samples_num);
                LOG_INF("Measurement time: %d",attr_meas_time_read.val1);
                LOG_INF("Number of samples: %d",attr_samples_num.val1);


                ret = sensor_sample_fetch(dev);
                if (ret != 0 ){
                        LOG_ERR("FETSH fail!!!!");
                        break;
                }

                sensor_channel_get(dev, SENSOR_CHAN_PM_1_0, &pm1);
                sensor_channel_get(dev, SENSOR_CHAN_PM_2_5, &pm_2_5);
                sensor_channel_get(dev, SENSOR_CHAN_PM_4, &pm_4);
                sensor_channel_get(dev, SENSOR_CHAN_PM_10, &pm_10);
                sensor_channel_get(dev, SENSOR_CHAN_PM_FAN_STATUS, &fan);
                sensor_channel_get(dev, SENSOR_CHAN_PM_SPEED_STATUS, &speed);
                sensor_channel_get(dev, SENSOR_CHAN_PM_LASER_STATUS, &laser);

                LOG_INF("main(): measured values:\n"
			"\t%d pm1\n"
			"\t%d pm2.5\n"
			"\t%d pm4\n"
			"\t%d pm10\n"
			"\t%d clean_interval_s_read\n"
			"\t%d meas_time_read\n"
			"\t%d samples_num\n"
			"\t%s Fan Status\n"
                        "\t%s Speed Status\n"
                        "\t%s Laser Status\n\n",
                        pm1.val1,
                        pm_2_5.val1,
                        pm_4.val1,
                        pm_10.val1,
                        clean_interval_s_read.val1,
                        attr_meas_time_read.val1,
                        attr_samples_num.val1,
                        fan.val1?"FAIL":"OK",
                        speed.val1?"FAIL":"OK",
                        laser.val1?"FAIL":"OK"
                        );

                k_sleep(K_MSEC(5000));

                // MANUAL FAN CLEANING
                manual_fan_cleaning_ms.val1 = 5000;
                LOG_INF(">>>>> Manual clean for %dms <<<<<<",manual_fan_cleaning_ms.val1);
                sensor_attr_set(dev,0,SENSOR_ATTR_AIR_QUALITY_MANUAL_CLEAN,(const struct sensor_value*)&manual_fan_cleaning_ms);

                LOG_INF("------ TEST #%d\n",++test_count);
                attr_meas_time.val1 = 10;
                attr_samples_num.val1 = 10;
                sensor_attr_set(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_DURATION_TIME_S,&attr_meas_time);
                sensor_attr_set(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_SAMPLES,&attr_samples_num);
                sensor_attr_get(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_DURATION_TIME_S,&attr_meas_time_read);
                sensor_attr_get(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_SAMPLES,&attr_samples_num);
                LOG_INF("Measurement time: %d",attr_meas_time_read.val1);
                LOG_INF("Number of samples: %d",attr_samples_num.val1);


                ret = sensor_sample_fetch(dev);
                if (ret != 0 ){
                        LOG_ERR("FETCH fail!!!!");
                        break;
                }

                sensor_channel_get(dev, SENSOR_CHAN_PM_1_0, &pm1);
                sensor_channel_get(dev, SENSOR_CHAN_PM_2_5, &pm_2_5);
                sensor_channel_get(dev, SENSOR_CHAN_PM_4, &pm_4);
                sensor_channel_get(dev, SENSOR_CHAN_PM_10, &pm_10);
                sensor_channel_get(dev, SENSOR_CHAN_PM_FAN_STATUS, &fan);
                sensor_channel_get(dev, SENSOR_CHAN_PM_SPEED_STATUS, &speed);
                sensor_channel_get(dev, SENSOR_CHAN_PM_LASER_STATUS, &laser);

                LOG_INF("main(): measured values:\n"
			"\t%d pm1\n"
			"\t%d pm2.5\n"
			"\t%d pm4\n"
			"\t%d pm10\n"
			"\t%d clean_interval_s_read\n"
			"\t%d meas_time_read\n"
			"\t%d samples_num\n"
			"\t%s Fan Status\n"
                        "\t%s Speed Status\n"
                        "\t%s Laser Status\n\n",
                        pm1.val1,
                        pm_2_5.val1,
                        pm_4.val1,
                        pm_10.val1,
                        clean_interval_s_read.val1,
                        attr_meas_time_read.val1,
                        attr_samples_num.val1,
                        fan.val1?"FAIL":"OK",
                        speed.val1?"FAIL":"OK",
                        laser.val1?"FAIL":"OK"
                        );
                
                k_sleep(K_MSEC(5000));

                LOG_INF("------ TEST #%d\n",++test_count);
                attr_meas_time.val1 = 5;
                attr_samples_num.val1 = 5;
                sensor_attr_set(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_DURATION_TIME_S,&attr_meas_time);
                sensor_attr_set(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_SAMPLES,&attr_samples_num);
                sensor_attr_get(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_DURATION_TIME_S,&attr_meas_time_read);
                sensor_attr_get(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_SAMPLES,&attr_samples_num);
                LOG_INF("Measurement time: %d",attr_meas_time_read.val1);
                LOG_INF("Number of samples: %d",attr_samples_num.val1);

                ret = sensor_sample_fetch(dev);
                if (ret != 0 ){
                        LOG_ERR("FETSH fail!!!!");
                        break;
                }

                sensor_channel_get(dev, SENSOR_CHAN_PM_1_0, &pm1);
                sensor_channel_get(dev, SENSOR_CHAN_PM_2_5, &pm_2_5);
                sensor_channel_get(dev, SENSOR_CHAN_PM_4, &pm_4);
                sensor_channel_get(dev, SENSOR_CHAN_PM_10, &pm_10);
                sensor_channel_get(dev, SENSOR_CHAN_PM_FAN_STATUS, &fan);
                sensor_channel_get(dev, SENSOR_CHAN_PM_SPEED_STATUS, &speed);
                sensor_channel_get(dev, SENSOR_CHAN_PM_LASER_STATUS, &laser);

                LOG_INF("main(): measured values:\n"
			"\t%d pm1\n"
			"\t%d pm2.5\n"
			"\t%d pm4\n"
			"\t%d pm10\n"
			"\t%d clean_interval_s_read\n"
			"\t%d meas_time_read\n"
			"\t%d samples_num\n"
			"\t%s Fan Status\n"
                        "\t%s Speed Status\n"
                        "\t%s Laser Status\n\n",
                        pm1.val1,
                        pm_2_5.val1,
                        pm_4.val1,
                        pm_10.val1,
                        clean_interval_s_read.val1,
                        attr_meas_time_read.val1,
                        attr_samples_num.val1,
                        fan.val1?"FAIL":"OK",
                        speed.val1?"FAIL":"OK",
                        laser.val1?"FAIL":"OK"
                        );
                
                k_sleep(K_MSEC(5000));
                attr_meas_time.val1 = 30;
                attr_samples_num.val1 = 30;
                sensor_attr_set(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_DURATION_TIME_S,&attr_meas_time);
                sensor_attr_set(dev,0,SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_SAMPLES,&attr_samples_num);
        }

        LOG_ERR("!!! SPS30 TEST ERROR !!!");
}
