package fi.nls.oskari.map.layer.formatters;

import fi.nls.oskari.domain.map.OskariLayer;
import fi.nls.oskari.domain.map.wfs.WFSLayerAttributes;
import fi.nls.oskari.domain.map.wfs.WFSLayerOptions;
import fi.nls.oskari.log.LogFactory;
import fi.nls.oskari.log.Logger;
import fi.nls.oskari.map.geometry.WKTHelper;
import fi.nls.oskari.service.ServiceException;
import fi.nls.oskari.service.capabilities.CapabilitiesConstants;
import fi.nls.oskari.util.JSONHelper;
import fi.nls.oskari.wfs.*;
import org.eclipse.emf.ecore.EObject;
import org.geotools.data.ResourceInfo;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.wfs.internal.WFSGetCapabilities;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS;
import org.json.JSONArray;
import org.json.JSONObject;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.GeometryDescriptor;
import org.oskari.service.wfs3.WFS3Service;

import java.util.Collections;
import java.util.Set;

import static fi.nls.oskari.service.capabilities.CapabilitiesConstants.*;
/**
 * Created with IntelliJ IDEA.
 * User: SMAKINEN
 * Date: 17.12.2013
 * Time: 15:37
 * To change this template use File | Settings | File Templates.
 */
public class LayerJSONFormatterWFS extends LayerJSONFormatter {

    private static final String KEY_WPS_PARAMS = "wps_params";

    private static Logger log = LogFactory.getLogger(LayerJSONFormatterWFS.class);

    public JSONObject getJSON(OskariLayer layer,
                                     final String lang,
                                     final boolean isSecure,
                                     final String crs) {

        final JSONObject layerJson = getBaseJSON(layer, lang, isSecure, crs);
        setStyles(layerJson, new WFSLayerOptions(layer.getOptions()));
        // Use maplayer setup
        if(layer.getStyle() == null || layer.getStyle().isEmpty() ){
            JSONHelper.putValue(layerJson, KEY_STYLE, "default");
        }
        else {
            JSONHelper.putValue(layerJson, KEY_STYLE, layer.getStyle());
        }
        JSONHelper.putValue(layerJson, KEY_ISQUERYABLE, true);
        WFSLayerAttributes attr = new WFSLayerAttributes(layer.getAttributes());
        JSONHelper.putValue(layerJson, KEY_WPS_PARAMS, getWpsParams(attr.getWpsParams()) );

        return layerJson;
    }

    /**
     * Constructs a style json
     *
     */
    protected void setStyles(JSONObject layerJson, WFSLayerOptions wfsOpts) {
        JSONHelper.putValue(layerJson, KEY_STYLES, wfsOpts.getStyles().names());
    }

    /**
     * Constructs wps params json
     *
     * @param  wpsParams wfs layer configuration
     */
    private JSONObject getWpsParams(String wpsParams) {

        JSONObject json = new JSONObject();
        if (wpsParams == null) return json;

        return JSONHelper.createJSONObject(wpsParams);

    }

    public static JSONObject createCapabilitiesJSON(final WFSGetCapabilities capa, SimpleFeatureSource source, Set<String> systemCRSs) throws ServiceException {

        try {
            JSONObject json;
            EObject parsedCapa = capa.getParsedCapabilities();
            if (parsedCapa instanceof net.opengis.wfs20.WFSCapabilitiesType) {
                json = WFSCapabilitiesParser200.parse(
                        (net.opengis.wfs20.WFSCapabilitiesType) parsedCapa);
            } else if (parsedCapa instanceof net.opengis.wfs.WFSCapabilitiesType) {
                json = WFSCapabilitiesParser110.parse(
                        (net.opengis.wfs.WFSCapabilitiesType) parsedCapa);
            } else {
                throw new ServiceException("Invalid WFSCapabilitiesType");
            }
            // parse for version 1.x
            // TODO: 2.0.0 or newer doesn't work with this so content-editor etc will not work with those
            // Schema is used only to parse geometry property name
            // skip if failed to get schema or can't find default geometry property
            try {
                SimpleFeatureType sft = source.getSchema();
                JSONHelper.putValue(json, CapabilitiesConstants.KEY_NAMESPACE_URL, sft.getName().getNamespaceURI());
                GeometryDescriptor geom = sft.getGeometryDescriptor();
                if (geom != null) {
                    JSONHelper.putValue(json, CapabilitiesConstants.KEY_GEOM_NAME, geom.getLocalName());
                } // TODO: else sft.getTypes().filter(known geom types)
            } catch (Exception e) {
                log.info("Unable to parse namespace url or geometry field name from schema:", e.getMessage());
            }

            ResourceInfo info = source.getInfo();
            // TODO is there more than default crs
            String crs = CRS.lookupIdentifier(info.getCRS(), true);
            if (crs != null) {
                Set<String> crss = getCRSsToStore(systemCRSs, Collections.singleton(crs));
                JSONHelper.put(json, KEY_SRS, new JSONArray(crss));
            }
            ReferencedEnvelope bbox = info.getBounds();
            if (bbox != null) {
                bbox = bbox.transform(WKTHelper.CRS_EPSG_4326, true);
                boolean coversWholeWorld = bbox.getMinX() <= -180 && bbox.getMinY() <= -90 && bbox.getMaxX() >= 180 && bbox.getMaxY() >= 90;
                if (!coversWholeWorld) {
                    // no need to attach coverage if it covers the whole world as it's not useful info
                    String wkt = WKTHelper.getBBOX(bbox.getMinX(), bbox.getMinY(), bbox.getMaxX(), bbox.getMaxY());
                    JSONHelper.putValue(json,KEY_LAYER_COVERAGE, wkt);
                }
            }
            Set<String> keywords = info.getKeywords();
            JSONHelper.putValue(json, KEY_KEYWORDS, new JSONArray(keywords));
            return json;
        } catch (Exception e) {
            throw new ServiceException( "Failed to create capabilities json: " + e.getMessage());

        }
    }
    public static JSONObject createCapabilitiesJSON (WFS3Service service, String collectionId, Set<String> systemCRSs) {
        JSONObject capabilities = new JSONObject(); // override
        Set<String> crsUri  = service.getSupportedCrsURIs(collectionId);
        JSONHelper.put(capabilities, KEY_CRS_URI, new JSONArray(crsUri));
        Set<String> capabilitiesCRSs = service.getSupportedEpsgCodes(collectionId);
        Set<String> crss = getCRSsToStore(systemCRSs, capabilitiesCRSs);
        JSONHelper.putValue(capabilities, KEY_SRS, new JSONArray(crss));
        Set<String> formats = service.getSupportedFormats(collectionId);
        JSONHelper.put(capabilities, KEY_FEATURE_OUTPUT_FORMATS, new JSONArray(formats));
        return capabilities;
    }

}

@@ -1321,72 +1321,8 @@
  %7B%0A%0A
-    private static final String KEY_WPS_PARAMS = %22wps_params%22;%0A%0A
     
@@ -1396,24 +1396,24 @@
 WFS.class);%0A
+
 %0A    public 
@@ -2113,181 +2113,8 @@
 ue);
-%0A        WFSLayerAttributes attr = new WFSLayerAttributes(layer.getAttributes());%0A        JSONHelper.putValue(layerJson, KEY_WPS_PARAMS, getWpsParams(attr.getWpsParams()) );
 %0A%0A  
@@ -2368,322 +2368,8 @@
  %7D%0A%0A
-    /**%0A     * Constructs wps params json%0A     *%0A     * @param  wpsParams wfs layer configuration%0A     */%0A    private JSONObject getWpsParams(String wpsParams) %7B%0A%0A        JSONObject json = new JSONObject();%0A        if (wpsParams == null) return json;%0A%0A        return JSONHelper.createJSONObject(wpsParams);%0A%0A    %7D%0A
 %0A   

remove unused wps_params from wfslayer json formatter