package cz.senslog.connector.model.converter;

import cz.senslog.connector.model.azure.AzureModel;
import cz.senslog.connector.model.azure.SensorData;
import cz.senslog.connector.model.azure.SensorInfo;
import cz.senslog.connector.model.v1.Observation;
import cz.senslog.connector.model.v1.Record;
import cz.senslog.connector.model.v1.SenslogV1Model;
import org.junit.jupiter.api.Test;

import java.time.*;
import java.util.ArrayList;
import java.util.List;

import static cz.senslog.connector.model.converter.AzureUnitConverter.convertSensorTypeToSensorId;
import static java.time.OffsetDateTime.MAX;
import static java.time.OffsetDateTime.MIN;
import static java.util.Collections.emptyList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

class AzureModelSenslogV1ModelConverterTest {

    @Test
    void convert_FullModel_True() {

        SensorData sensorData = new SensorData();
        sensorData.setTime(OffsetDateTime.of(LocalDateTime.of(1970, Month.JANUARY, 1, 0,0,0), ZoneOffset.UTC));
        sensorData.setBatteryLevel(100.0F);
        sensorData.setCo2(600.0F);
        sensorData.setHumidity(50.0F);
        sensorData.setRssi(-150);
        sensorData.setSnr(3F);
        sensorData.setTemperature(25.0F);

        List<SensorData> sensorInfoData = new ArrayList<>(1);
        sensorInfoData.add(sensorData);

        SensorInfo sensorInfo = new SensorInfo();
        sensorInfo.setEui("8CF9574000000948");
        sensorInfo.setData(sensorInfoData);

        List<SensorInfo> sensors = new ArrayList<>(1);
        sensors.add(sensorInfo);

        AzureModel azureModel = new AzureModel(sensors, MIN, MAX);

        AzureModelSenslogV1ModelConverter converter = new AzureModelSenslogV1ModelConverter();
        SenslogV1Model senslogV1Model = converter.convert(azureModel);

        List<Record> observations = senslogV1Model.getObservations();
        assertEquals(6, observations.size());

        for (Record record : observations) {
            Observation observation = (Observation)record;

            assertEquals(10002376L, observation.getUnitId());
            assertEquals("1970-01-01 00:00:00+0000", observation.getFormattedTime());

            if (observation.getSensorId().equals(convertSensorTypeToSensorId("8CF9574000000948", "batteryLevel"))) {
                assertEquals(100.0F, observation.getValue());
            } else if (observation.getSensorId().equals(convertSensorTypeToSensorId("8CF9574000000948", "humidity"))) {
                assertEquals(50.0F, observation.getValue());
            } else if (observation.getSensorId().equals(convertSensorTypeToSensorId("8CF9574000000948", "co2"))) {
                assertEquals(600.0F, observation.getValue());
            } else if (observation.getSensorId().equals(convertSensorTypeToSensorId("8CF9574000000948", "rssi"))) {
                assertEquals(-150, observation.getValue());
            } else if (observation.getSensorId().equals(convertSensorTypeToSensorId("8CF9574000000948", "snr"))) {
                assertEquals(3F, observation.getValue());
            } else if (observation.getSensorId().equals(convertSensorTypeToSensorId("8CF9574000000948", "temperature"))) {
                assertEquals(25.0F, observation.getValue());
            }
        }
    }

    @Test
    void convert_EmptyModel_Null() {

        AzureModel azureModel = new AzureModel(null, null, null);

        AzureModelSenslogV1ModelConverter converter = new AzureModelSenslogV1ModelConverter();

        SenslogV1Model senslogV1Model = converter.convert(azureModel);

        assertNull(senslogV1Model);
    }

    @Test
    void convert_NullModel_Null() {

        AzureModelSenslogV1ModelConverter converter = new AzureModelSenslogV1ModelConverter();

        SenslogV1Model senslogV1Model = converter.convert(null);

        assertNull(senslogV1Model);
    }

    @Test
    void convert_EmptySensors_EmptyModel() {

        AzureModel azureModel = new AzureModel(emptyList(), MIN, MAX);

        AzureModelSenslogV1ModelConverter converter = new AzureModelSenslogV1ModelConverter();

        SenslogV1Model senslogV1Model = converter.convert(azureModel);

        assertEquals(0, senslogV1Model.getObservations().size());
    }

    @Test
    void convert_UnknownSensor_EmptyModel() {

        SensorInfo sensorInfo = new SensorInfo();
        sensorInfo.setEui("1234");
        sensorInfo.setData(new ArrayList<>());

        List<SensorInfo> sensors = new ArrayList<>(1);
        sensors.add(sensorInfo);

        AzureModel azureModel = new AzureModel(sensors, MIN, MAX);

        AzureModelSenslogV1ModelConverter converter = new AzureModelSenslogV1ModelConverter();
        SenslogV1Model senslogV1Model = converter.convert(azureModel);


        assertEquals(0, senslogV1Model.getObservations().size());
    }
}