package fi.nls.oskari.control.statistics.plugins.user;

import fi.mml.map.mapwindow.service.db.UserIndicatorService;
import fi.mml.map.mapwindow.service.db.UserIndicatorServiceImpl;
import fi.nls.oskari.control.statistics.data.*;
import fi.nls.oskari.control.statistics.plugins.StatisticalDatasourcePlugin;
import fi.nls.oskari.domain.User;
import fi.nls.oskari.domain.map.indicator.UserIndicator;
import fi.nls.oskari.log.LogFactory;
import fi.nls.oskari.log.Logger;
import fi.nls.oskari.util.JSONHelper;
import fi.nls.oskari.util.PropertyUtil;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.*;

public class UserIndicatorsStatisticalDatasourcePlugin extends StatisticalDatasourcePlugin {
    private final static Logger LOG = LogFactory.getLogger(UserIndicatorsStatisticalDatasourcePlugin.class);
    private static UserIndicatorService userIndicatorService = new UserIndicatorServiceImpl();

    public UserIndicatorsStatisticalDatasourcePlugin() {
    }

    @Override
    public IndicatorSet getIndicatorSet(User user) {
        IndicatorSet set = new IndicatorSet();
        if(user != null) {
            set.setIndicators(getIndicators(user));
            set.setComplete(true);
        }
        return set;
    }

    public void update() {
        // NO-OP - getIndicatorSet responds immediately
    }

    private List<StatisticalIndicator> getIndicators(User user) {
        // Getting the general information of all the indicator layers.
        if (user == null) {
            return new ArrayList<>();
        }
        long uid = user.getId();
        List<UserIndicator> userIndicators = userIndicatorService.findAllOfUser(uid);
        return toUserStatisticalIndicators(userIndicators);
    }

    private List<StatisticalIndicator> toUserStatisticalIndicators(List<UserIndicator> userIndicators) {
        List<StatisticalIndicator> indicators = new ArrayList<>();
        final String language = PropertyUtil.getDefaultLanguage();
        for (UserIndicator userIndicator : userIndicators) {
            StatisticalIndicator ind = new StatisticalIndicator();
            ind.setId(String.valueOf(userIndicator.getId()));

            JSONObject title = JSONHelper.createJSONObject(userIndicator.getTitle());
            Iterator<String> langKeys = title.keys();
            while(langKeys.hasNext()) {
                String lang = langKeys.next();
                ind.addName(lang, title.optString(lang));
            }

            JSONObject source = JSONHelper.createJSONObject(userIndicator.getSource());
            langKeys = source.keys();
            while(langKeys.hasNext()) {
                String lang = langKeys.next();
                ind.addSource(lang, source.optString(lang));
            }

            JSONObject desc = JSONHelper.createJSONObject(userIndicator.getDescription());
            langKeys = desc.keys();
            while(langKeys.hasNext()) {
                String lang = langKeys.next();
                ind.addSource(lang, desc.optString(lang));
            }
            ind.setPublic(userIndicator.isPublished());
            ind.addLayer(new StatisticalIndicatorLayer(userIndicator.getMaterial(), ind.getId()));

            // If we want to provide year, need to do it like this. But currently there's always just one choice
            StatisticalIndicatorDataDimension dim = new StatisticalIndicatorDataDimension("year");
            dim.addAllowedValue(String.valueOf(userIndicator.getYear()));
            ind.getDataModel().addDimension(dim);
            indicators.add(ind);
        }
        return indicators;
    }

    @Override
    public boolean canCache() {
        // Because the results are based on the user doing the query, we should not cache here.
        return false;
    }

    @Override
    public Map<String, IndicatorValue> getIndicatorValues(StatisticalIndicator indicator,
                                                          StatisticalIndicatorDataModel params,
                                                          StatisticalIndicatorLayer regionset) {
        // Data is a serialized JSON for legacy and backwards compatibility reasons:
        // "data":[{"region":"727","primary value":"15"},{"region":"728","primary value":"20"}]
        UserIndicator userIndicator = userIndicatorService.find(indicator.getId());
        Map<String, IndicatorValue> valueMap = new HashMap<>();
        try {
            JSONArray jsonData = new JSONArray(userIndicator.getData());
            for (int i = 0; i < jsonData.length(); i++) {
                JSONObject value = jsonData.getJSONObject(i);
                IndicatorValueFloat indicatorValue = new IndicatorValueFloat(value.getDouble("primary value"));
                valueMap.put(value.getString("region"), indicatorValue);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return valueMap;
    }
}

@@ -175,16 +175,57 @@
 ceImpl;%0A
+import fi.nls.oskari.cache.JedisManager;%0A
 import f
@@ -264,16 +264,16 @@
 data.*;%0A
-
 import f
@@ -498,24 +498,68 @@
 log.Logger;%0A
+import fi.nls.oskari.util.ConversionHelper;%0A
 import fi.nl
@@ -711,16 +711,44 @@
 bject;%0A%0A
+import java.io.IOException;%0A
 import j
@@ -2053,75 +2053,8 @@
 ();%0A
-        final String language = PropertyUtil.getDefaultLanguage();%0A
     
@@ -3848,32 +3848,605 @@
 n false;%0A    %7D%0A%0A
+    /**%0A     * Override as default impl expects indicators are stored in redis%0A     * @param user%0A     * @param indicatorId%0A     * @return%0A     */%0A    @Override%0A    public StatisticalIndicator getIndicator(User user, String indicatorId) %7B%0A        // TODO: optimize to load single indicator or change indicatorset to be stored in redis%0A        List%3CStatisticalIndicator%3E list = getIndicators(user);%0A        for(StatisticalIndicator ind: list) %7B%0A            if(ind.getId().equals(indicatorId)) %7B%0A                return ind;%0A            %7D%0A        %7D%0A        return null;%0A    %7D%0A
     @Override%0A  
@@ -4971,16 +4971,40 @@
 ce.find(
+ConversionHelper.getInt(
 indicato
@@ -5012,16 +5012,21 @@
 .getId()
+, -1)
 );%0A     

Fix for metadata/data loading for user indicators