package fi.nls.oskari.control.layer;

import fi.nls.oskari.analysis.AnalysisHelper;
import fi.nls.oskari.annotation.OskariActionRoute;
import fi.nls.oskari.control.ActionException;
import fi.nls.oskari.control.ActionHandler;
import fi.nls.oskari.control.ActionParameters;
import fi.nls.oskari.control.ActionParamsException;
import fi.nls.oskari.domain.User;
import fi.nls.oskari.domain.map.analysis.Analysis;
import fi.nls.oskari.log.LogFactory;
import fi.nls.oskari.log.Logger;
import fi.nls.oskari.map.analysis.service.AnalysisDbService;
import fi.nls.oskari.map.analysis.service.AnalysisDbServiceIbatisImpl;
import fi.nls.oskari.util.ConversionHelper;
import fi.nls.oskari.util.JSONHelper;
import fi.nls.oskari.util.ResponseHelper;
import org.json.JSONArray;
import org.json.JSONObject;

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

/**
 * Returns user's analysis data as JSON.
 */
@OskariActionRoute("GetAnalysisData")
public class GetAnalysisDataHandler extends ActionHandler {

    private static final Logger log = LogFactory.getLogger(GetAnalysisDataHandler.class);
    private static final AnalysisDbService analysisService = new AnalysisDbServiceIbatisImpl();

    private static final String ANALYSE_ID = "analyse_id";
    private static final String JSKEY_ANALYSISDATA = "analysisdata";

    @Override
    public void handleAction(ActionParameters params) throws ActionException {

        // only for logged in users!
        params.requireLoggedInUser();

        final long id = ConversionHelper.getLong(params.getHttpParam(ANALYSE_ID), -1);
        if (id == -1) {
            throw new ActionParamsException("Parameter missing or non-numeric: " + ANALYSE_ID + "=" + params.getHttpParam(ANALYSE_ID));
        }

        final User user = params.getUser();
        // Get analysis select items
        final Analysis analysis = analysisService.getAnalysisById(id);
        final String select_items = AnalysisHelper.getAnalysisSelectItems(analysis);

        final JSONObject response = new JSONObject();
        if (select_items != null) {

            final List<HashMap<String, Object>> list = analysisService.getAnalysisDataByIdUid(id, user.getUuid(), select_items);
            final JSONArray rows = new JSONArray();
            for (HashMap<String, Object> analysisData : list) {
                final JSONObject row = convertMapToJSON(analysisData);
                if(row != null) {
                    rows.put(row);
                }
            }
            JSONHelper.putValue(response, JSKEY_ANALYSISDATA, rows);
            JSONHelper.putValue(response, ANALYSE_ID, id);
        }

        ResponseHelper.writeResponse(params, response);
    }

    /**
     * Converts any stringified JSON in Map values to proper JSON object values
     * and returns the Map as a JSONObject
     * @param analysisData
     * @return
     */
    private JSONObject convertMapToJSON(HashMap<String, Object> analysisData) {
        if(analysisData == null) {
            return null;
        }

        for (Map.Entry<String, Object> entry : analysisData.entrySet()) {
            final Object value = entry.getValue();
            if(value.toString().indexOf("{") == -1) {
                // not json, skip to next one
                continue;
            }
            // try to map as JSON
            final JSONObject modifiedValue = JSONHelper.createJSONObject(value.toString());
            if(modifiedValue != null) {
                entry.setValue(modifiedValue);
            }
        }
        return new JSONObject(analysisData);
    }
}

@@ -901,16 +901,45 @@
 s JSON.%0A
+ * Only for aggregate method%0A
  */%0A@Osk
@@ -2393,29 +2393,35 @@
 ow = convert
-MapTo
+ToOldResult
 JSON(analysi
@@ -2421,24 +2421,38 @@
 analysisData
+, select_items
 );%0A         
@@ -2460,16 +2460,17 @@
       if
+ 
 (row != 
@@ -2775,70 +2775,84 @@
 ts a
-ny stringified JSON in Map values to proper JSON object values
+ggregate analysis result to old result syntax for multiselect on client side
 %0A   
@@ -2871,19 +2871,8 @@
 rns 
-the Map as 
 a JS
@@ -2883,50 +2883,156 @@
 ject
-%0A     * @param analysisData%0A     * @return
+ as aggregate results of one property%0A     *%0A     * @param analysisData%0A     * @return JSONObject %7Bproperty:%7Baggregate value1, aggregate value2,..%7D%7D
 %0A   
@@ -3070,13 +3070,19 @@
 vert
-MapTo
+ToOldResult
 JSON
@@ -3118,16 +3118,38 @@
 ysisData
+, String selectColumns
 ) %7B%0A    
@@ -3154,16 +3154,17 @@
       if
+ 
 (analysi
@@ -3207,32 +3207,114 @@
 null;%0A        %7D%0A
+        final JSONObject row = new JSONObject();%0A        String columnName = null;
 %0A        for (Ma
@@ -3439,42 +3439,95 @@
     
-if(value.toString().indexOf(%22%7B%22) =
+final String key = entry.getKey();%0A            if (selectColumns.indexOf(%22As %22 + key) !
 = -1
@@ -3550,37 +3550,38 @@
     
-// not json, skip to next one
+columnName = value.toString();
 %0A   
@@ -3667,127 +3667,46 @@
     
-final JSONObject modifiedValue = JSONHelper.createJSONObject(value.toString());%0A            if(modifiedValue != null) %7B
+JSONHelper.putValue(row, key, value);%0A
 %0A   
@@ -3710,24 +3710,26 @@
         
+%7D%0A
         
 entry.se
@@ -3724,106 +3724,89 @@
     
-entry.setValue(modifiedValue);%0A            %7D%0A        %7D%0A        return new JSONObject(analysisData)
+return (columnName != null) ? JSONHelper.createJSONObject(columnName, row) : null
 ;%0A  

use statical values in wfs filter dialog is fixed