package cz.senslog.connector.model.converter;

import cz.senslog.connector.model.alapans.AlapansModel;
import cz.senslog.connector.model.alapans.UnitData;
import cz.senslog.connector.model.api.Converter;
import cz.senslog.connector.model.v1.Observation;
import cz.senslog.connector.model.v1.Record;
import cz.senslog.connector.model.v1.SenslogV1Model;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;
import java.util.function.Function;

public class AlapansModelSenslogV1ModelConverter implements Converter<AlapansModel, SenslogV1Model> {

    private static final Logger logger = LogManager.getLogger(AlapansModelSenslogV1ModelConverter.class);

    private static final Map<String, Long> DEVICE_ID_TO_UNIT_ID;

    private static final Function<UnitData, List<Observation>> SENSOR_MAPPING_FNC;
    private static final int NM_OF_SENSORS;

    static {
        DEVICE_ID_TO_UNIT_ID = new HashMap<>();

        DEVICE_ID_TO_UNIT_ID.put("eui-ac1f09fffe05335e", 428059001L);
        DEVICE_ID_TO_UNIT_ID.put("eui-ac1f09fffe053381", 428059002L);
        DEVICE_ID_TO_UNIT_ID.put("eui-ac1f09fffe05335c", 428059003L);
        DEVICE_ID_TO_UNIT_ID.put("eui-ac1f09fffe053359", 428059004L);
        DEVICE_ID_TO_UNIT_ID.put("eui-ac1f09fffe05335f", 428059200L);
        DEVICE_ID_TO_UNIT_ID.put("eui-ac1f09fffe053363", 428059005L);

        NM_OF_SENSORS = 6;
        SENSOR_MAPPING_FNC = (u) -> Arrays.asList(
                new Observation(){{setSensorId(340020000L); setValue(u.getAirTemperature());    }},
                new Observation(){{setSensorId(410010000L); setValue(u.getAirHumidity());       }},
                new Observation(){{setSensorId(340031000L); setValue(u.getSoilTemperature1());  }},
                new Observation(){{setSensorId(340032000L); setValue(u.getSoilTemperature2());  }},
                new Observation(){{setSensorId(410021000L); setValue(u.getSoilMoisture1());     }},
                new Observation(){{setSensorId(410022000L); setValue(u.getSoilMoisture2());     }},
                new Observation(){{setSensorId(360010000L); setValue(u.getBatteryVoltage());    }}
        );
    }


    @Override
    public SenslogV1Model convert(AlapansModel inputModel) {
        if (inputModel == null) { return null; }
        List<Record> observations = new ArrayList<>(inputModel.getUnitData().size() * NM_OF_SENSORS);
        for (UnitData unitData : inputModel.getUnitData()) {
            for (Observation observation : SENSOR_MAPPING_FNC.apply(unitData)) {
                if (observation.getValue() == null) { continue; }
                Long unitId = DEVICE_ID_TO_UNIT_ID.get(unitData.getDeviceId());
                if (unitId == null) {
                    logger.warn("The device ID {} is not registered.", unitData.getDeviceId()); continue;
                }
                observation.setUnitId(unitId);
                observation.setTime(unitData.getTimestamp());
                observations.add(observation);
            }
        }
        return new SenslogV1Model(observations, inputModel.getFrom(), inputModel.getTo());
    }
}