package fi.nls.oskari.control.view.modifier.param;

import fi.nls.oskari.annotation.OskariViewModifier;
import fi.nls.oskari.view.modifier.ParamHandler;
import fi.nls.oskari.log.LogFactory;
import fi.nls.oskari.log.Logger;
import fi.nls.oskari.view.modifier.ModifierException;
import fi.nls.oskari.view.modifier.ModifierParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

@OskariViewModifier("mapLayers")
public class LayersParamHandler extends ParamHandler {

    private static final Logger log = LogFactory.getLogger(LayersParamHandler.class);
    private static final String PARAM_LAYERS = "mapLayers";
    private static final String KEY_OPACITY = "opacity";
    private static final String KEY_STYLE = "style";
    private static final String KEY_ID = "id";
    private static final String KEY_LAYERS = "layers";
    private static final String KEY_SEL_LAYERS = "selectedLayers";

    private static final String PREFIX_MYPLACES = "myplaces_";
    
    public boolean handleParam(final ModifierParams params) throws ModifierException {
        if(params.getParamValue() == null) {
            return false;
        }

        final String[] layers = params.getParamValue().split(",");
        final JSONArray layersJson = new JSONArray();
        
        for (String layerString : layers) {
            final String[] layerProps = layerString.split(" ");
            final JSONObject layer =  getLayerJson(layerProps, params.getReferer());
            if(layer != null) {
                layersJson.put(layer);
            }
        }

        try {
            final JSONObject mapfullConfig = getBundleConfig(params.getConfig(), BUNDLE_MAPFULL);
            final JSONObject mapfullState = getBundleState(params.getConfig(), BUNDLE_MAPFULL);
            // TODO: maybe check if config had more layers than state
            mapfullState.put(KEY_SEL_LAYERS, layersJson);
            mapfullConfig.put(KEY_LAYERS, layersJson);
        } catch (JSONException je) {
            throw new ModifierException("Could not replace layer arrays");
        }
        return false;
    }
    
    public static JSONObject getLayerJson(final String[] layerParam, final String referer) throws ModifierException {

        final String layerId = layerParam[0];

        // Skipping myplaces_.* as they get created in JS
        if (layerId.startsWith(PREFIX_MYPLACES)) {
            // FIXME: handle same way as UNRESTRICTED_USAGE_DOMAINS in GetAppSetupHandler?
            if (!(referer.endsWith("paikkatietoikkuna.fi")
                    || referer.endsWith("nls.fi"))) {
                // not paikkatietoikkuna or nls -> skip myplaces layer
                // otherwise continue so links to published layers work
                // etc
                return null;
            }
        }
        final String layerOpacity = layerParam.length > 1 ? layerParam[1]
                : "100";
        final String layerStyle = layerParam.length > 2 ? layerParam[2]
                : null;

        final JSONObject layer = new JSONObject();
        try {
            layer.put(KEY_ID, layerId);
            layer.put(KEY_OPACITY, layerOpacity);
            if (layerStyle != null) {
                layer.put(KEY_STYLE, layerStyle);
            }
            return layer;
        } catch (JSONException je) {
            log.warn("Could not create layer JSON from params:", layerParam);
            throw new ModifierException("Could not populate layer JSON");
        }
    }
    
}

@@ -212,24 +212,288 @@
 log.Logger;%0A
+import fi.nls.oskari.map.layer.externalid.OskariLayerExternalId;%0Aimport fi.nls.oskari.map.layer.externalid.OskariLayerExternalIdService;%0Aimport fi.nls.oskari.map.layer.externalid.OskariLayerExternalIdServiceMybatisImpl;%0Aimport fi.nls.oskari.util.ConversionHelper;%0A
 import fi.nl
@@ -851,68 +851,8 @@
 s);%0A
-    private static final String PARAM_LAYERS = %22mapLayers%22;%0A
     
@@ -1190,16 +1190,139 @@
 aces_%22;%0A
+    private static final OskariLayerExternalIdService EXTERNAL_ID_SERVICE = new OskariLayerExternalIdServiceMybatisImpl();%0A
     %0A   
@@ -2570,25 +2570,24 @@
 ption %7B%0A
-%0A
         
 final St
@@ -2570,38 +2570,32 @@
 ption %7B%0A        
-final 
 String layerId =
@@ -2611,16 +2611,421 @@
 am%5B0%5D;%0A%0A
+        // Check if the layerId is the externalId of a maplayer%0A        if (ConversionHelper.getInt(layerId, -1) == -1) %7B%0A            OskariLayerExternalId externalId = EXTERNAL_ID_SERVICE.findByExternalId(layerId);%0A            if (externalId != null) %7B%0A                // If it is, use the maplayer id instead%0A                layerId = Integer.toString(externalId.getLayerId());%0A            %7D%0A        %7D%0A%0A
         

Replace externalIds of maplayers with the matching layer id in LayersParamHandler