// Copyright (c) 2020 UWB & LESP.
// The UWB & LESP license this file to you under the MIT license.

package cz.senslog.connector.model.converter;


import cz.senslog.connector.tools.util.Tuple;

import java.util.HashMap;
import java.util.Map;

import static cz.senslog.connector.model.afarcloud.MeasurementType.SENSOR;

public final class AFarCloudUnitSensorConverter {

    private final static ReverseMap<Long, String> UNITS = new ReverseMap<>();
    private final static Map<Long, ReverseMap<Long, String>> SENSORS = new HashMap<>();
    private final static Map<Long, AFarCloudUnitProperties> UNIT_PROPERTIES = new HashMap<>();

    private static void register(long unitId, String resourceId, ReverseMap<Long, String> sensorsReverseMap, AFarCloudUnitProperties properties) {
        UNITS.put(unitId, resourceId);
        SENSORS.put(unitId, sensorsReverseMap);
        UNIT_PROPERTIES.put(unitId, properties);
    }

    static {
        // 20046337L
        ReverseMap<Long, String> sensors = new ReverseMap<>();

        sensors.put(340470000L, "rumen_temperature");
        sensors.put(590030000L, "pH");
        sensors.put(600030000L, "orp");

        register(20046337L, "200463370", sensors,
                new AFarCloudUnitProperties(SENSOR)
        );
    }

    static {
        // 20062496L
        ReverseMap<Long, String> sensors = new ReverseMap<>();

        sensors.put(340470000L, "rumen_temperature");
        sensors.put(590030000L, "pH");
        sensors.put(600030000L, "orp");

        register(20062496L, "200624960", sensors,
                new AFarCloudUnitProperties(SENSOR)
        );
    }

    static {
        // 10002376L
        ReverseMap<Long, String> sensors = new ReverseMap<>();

        sensors.put(340020000L, "air_temperature");
        sensors.put(410010000L, "air_humidity");
        sensors.put(560030000L, "battery");

        register(10002376L, "10002376", sensors,
                new AFarCloudUnitProperties(SENSOR)
        );
    }

    static {
        // 10002222L
        ReverseMap<Long, String> sensors = new ReverseMap<>();

        sensors.put(340020000L, "air_temperature");
        sensors.put(410010000L, "air_humidity");
        sensors.put(560030000L, "battery");

        register(10002222L, "10002222", sensors,
                new AFarCloudUnitProperties(SENSOR)
        );
    }

    static {
        // 1305167561991327L
        ReverseMap<Long, String> sensors = new ReverseMap<>();

        sensors.put(340380097L, "air_temperature");
        sensors.put(410150097L, "air_humidity");
        sensors.put(360200000L, "battery");
        sensors.put(780010097L, "co2");

        register(1305167561991327L, "1305167561991327", sensors,
                new AFarCloudUnitProperties(SENSOR)
        );
    }

    static {
        // 1305167562028072L
        ReverseMap<Long, String> sensors = new ReverseMap<>();

        sensors.put(340380097L, "air_temperature");
        sensors.put(410150097L, "air_humidity");
        sensors.put(360200000L, "battery");
        sensors.put(780010097L, "co2");

        register(1305167562028072L, "1305167562028072", sensors,
                new AFarCloudUnitProperties(SENSOR)
        );
    }

    static {
        // 1305167562287832
        ReverseMap<Long, String> sensors = new ReverseMap<>();

        sensors.put(340420000L, "air_temperature");
        sensors.put(410180000L, "air_humidity");
        sensors.put(360200000L, "battery");
        sensors.put(460090000L, "air_pressure");
        sensors.put(470160000L, "wind_speed");
        sensors.put(470180000L, "wind_direction");
        sensors.put(480080000L, "rainfall");
        sensors.put(620030000L, "solar_radiation");

        register(1305167562287832L, "1305167562287832", sensors,
                new AFarCloudUnitProperties(SENSOR)
        );
    }

    static {
        // 1305167562017824
        ReverseMap<Long, String> sensors = new ReverseMap<>();

        sensors.put(340380097L, "air_temperature");
        sensors.put(410150097L, "air_humidity");
        sensors.put(360200000L, "battery");
        sensors.put(780010097L, "co2");

        register(1305167562017824L, "1305167562017824", sensors,
                new AFarCloudUnitProperties(SENSOR)
        );
    }

    public static long afcResourceIdToSensLogUnitId(String resourceId) {
        Long unitId = UNITS.getKey(resourceId);
        return unitId != null ? unitId : -1;
    }

    public static Tuple<Long, Long> afcToSensLog(String resourceId, String observedProperty) {
        Long unitId = UNITS.getKey(resourceId);
        if (unitId == null) {
            return null;
        }
        ReverseMap<Long, String> sensors = SENSORS.get(unitId);
        if (sensors == null) {
            return null;
        }

        Long sensorId = sensors.getKey(observedProperty);
        if (sensorId == null) {
            return null;
        }

        return Tuple.of(unitId, sensorId);
    }

    public static Tuple<String, AFarCloudUnitProperties> sensLogUnitIdToAfcResourceId(long unitId) {
        return Tuple.of(UNITS.getValue(unitId), UNIT_PROPERTIES.get(unitId));
    }

    public static String sensLogSensorIdToAfcObservedProperty(long unitId, long sensorId) {
        ReverseMap<Long, String> sensors = SENSORS.get(unitId);
        if (sensors == null) {
            return null;
        }
        return sensors.getValue(sensorId);
    }

    public static Tuple<String, String> sensLogToAfc(long unitId, long sensorId) {
        String resourceId = UNITS.getValue(unitId);
        if (resourceId == null) {
            return null;
        }
        ReverseMap<Long, String> sensors = SENSORS.get(unitId);
        if (sensors == null) {
            return null;
        }
        String observedProperty = sensors.getValue(sensorId);
        if (observedProperty == null) {
            return null;
        }
        return Tuple.of(resourceId, observedProperty);
    }
}
