package cz.senslog.connector.model.converter;

import cz.senslog.connector.model.drutes.DrutesModel;
import cz.senslog.connector.model.drutes.PredictionData;
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.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.util.*;

import static java.time.format.DateTimeFormatter.ofPattern;
import static org.junit.jupiter.api.Assertions.*;

class DrutesModelSenslogV1ModelConverterTest {

    @Test // happy scenario
    void convert() {

        final long timeShift = 604800;

        OffsetDateTime predictCreated = LocalDateTime.of(2022, 3, 9, 13, 26, 42, 0)
                .atZone(ZoneId.systemDefault()).toOffsetDateTime();
        OffsetDateTime predictionFrom = LocalDateTime.of(2021, 11, 2, 16, 0,0,0)
                .atZone(ZoneId.systemDefault()).toOffsetDateTime();
        OffsetDateTime predictionTo = predictionFrom.plusSeconds(timeShift);

        List<PredictionData> predictions = Arrays.asList(
                new PredictionData(4151559L, 340260001L, timeShift, new double[]{-1}, predictCreated, predictionFrom),
                new PredictionData(4151559L, 340260002L, timeShift, new double[]{-2}, predictCreated, predictionFrom),
                new PredictionData(4151559L, 710010001L, timeShift, new double[]{-3, 3}, predictCreated, predictionFrom),
                new PredictionData(4151559L, 710010002L, timeShift, new double[]{-4, 4}, predictCreated, predictionFrom)
        );

        DrutesModel drutesModel = new DrutesModel(predictions, predictionFrom, predictionTo);

        SenslogV1Model senslogV1Model = new DrutesModelSenslogV1ModelConverter().convert(drutesModel);

        assertEquals(6, senslogV1Model.getObservations().size());
        for (Record rec : senslogV1Model.getObservations()) {

            assertEquals(4151559L, rec.getUnitId());
            assertEquals(predictionTo, rec.getTime());
            assertEquals(Observation.class, rec.getClass());

            Observation obs = (Observation)rec;
            int sensorId = obs.getSensorId().intValue();
            double value = obs.getValue();

            switch (sensorId) {
                case 340593001 : assertEquals(-1, value); break;
                case 340593002 : assertEquals(-2, value); break;
                case 710063001 : assertEquals(-3, value); break;
                case 890023001 : assertEquals(3, value); break;
                case 710063002 : assertEquals(-4, value); break;
                case 890023002 : assertEquals(4, value); break;
                default: fail(String.format("Sensor ID '%d' is not defined.", sensorId));
            }
        }
    }
}