<commit_before>package com.cgi.eoss.fstep.catalogue.geoserver;

import static it.geosolutions.geoserver.rest.encoder.GSResourceEncoder.ProjectionPolicy.REPROJECT_TO_DECLARED;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.cgi.eoss.fstep.catalogue.IngestionException;
import com.cgi.eoss.fstep.catalogue.geoserver.model.GeoserverImportTask;
import com.cgi.eoss.fstep.catalogue.geoserver.model.GeoserverImportTask.UpdateMode;
import com.cgi.eoss.fstep.catalogue.util.GeoUtil;
import com.cgi.eoss.fstep.model.GeoserverLayer;
import com.cgi.eoss.fstep.model.GeoserverLayer.StoreType;
import com.fasterxml.jackson.core.JsonProcessingException;

import it.geosolutions.geoserver.rest.GeoServerRESTManager;
import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
import it.geosolutions.geoserver.rest.GeoServerRESTReader;
import it.geosolutions.geoserver.rest.decoder.RESTCoverageStore;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
import it.geosolutions.geoserver.rest.encoder.GSPostGISDatastoreEncoder;
import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder;
import it.geosolutions.geoserver.rest.encoder.coverage.GSCoverageEncoder;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
import okhttp3.HttpUrl;

@Component
@Log4j2
public class GeoserverServiceImpl implements GeoserverService {

    private static final String RASTER_STYLE = "raster";

    @Getter
    private final HttpUrl externalUrl;
    private final GeoServerRESTPublisher publisher;
    private final GeoServerRESTReader reader;

    @Value("${fstep.catalogue.geoserver.enabled:true}")
    private boolean geoserverEnabled;

    private Set<String> ingestableFiletypes;

    private GeoserverMosaicManager mosaicManager;

	private GeoserverImporter importer;
	
	private String postgisStore;
	
	private String postgisWorkspace;

	private String postgisHost;

	private int postgisPort;

	private String postgisDb;

	private String postgisUsername;

	private String postgisPassword;

	@Autowired
    public GeoserverServiceImpl(@Value("${fstep.catalogue.geoserver.url:http://fstep-geoserver:9080/geoserver/}") String url,
            @Value("${fstep.catalogue.geoserver.externalUrl:http://fstep-geoserver:9080/geoserver/}") String externalUrl,
            @Value("#{'${fstep.catalogue.geoserver.ingest-filetypes:TIF}'.split(',')}") Set<String> ingestableFiletypes,
            @Value("${fstep.catalogue.geoserver.username:fstepgeoserver}") String username,
            @Value("${fstep.catalogue.geoserver.password:<PASSWORD>}") String password,
            @Value("${fstep.catalogue.geoserver.postgisHost:fstepdb}") String postgisHost,
            @Value("${fstep.catalogue.geoserver.postgisPort:5432}") int postgisPort,
            @Value("${fstep.catalogue.geoserver.postgisDb:fstepgeoserver}") String postgisDb,
            @Value("${fstep.catalogue.geoserver.postgisUsername:fstepgeoserverPostgis}") String postgisUsername,
            @Value("${fstep.catalogue.geoserver.postgisPassword:<PASSWORD>verPostgispass}") String postgisPassword,
            @Value("${fstep.catalogue.geoserver.postgisStore:fstepgeoserverPostgisStore}") String postgisStore,
            @Value("${fstep.catalogue.geoserver.postgisWorkspace:fstepgeoserverPostgisWorkspace}") String postgisWorkspace
            ) throws MalformedURLException {
        this.externalUrl = HttpUrl.parse(externalUrl);
        GeoServerRESTManager geoserver = new GeoServerRESTManager(new URL(url), username, password);
        if (ingestableFiletypes == null){
        	ingestableFiletypes = new HashSet<>();
        }
        this.ingestableFiletypes = ingestableFiletypes;
        this.reader = geoserver.getReader();
        this.publisher = geoserver.getPublisher();
        this.importer = new GeoserverImporter(new URL(url), username, password);
        this.mosaicManager = new GeoserverMosaicManager(reader, new URL(url), username, password, postgisHost, postgisPort, postgisDb, postgisUsername, postgisPassword);
        this.postgisStore = postgisStore;
        this.postgisWorkspace = postgisWorkspace;
        this.postgisHost = postgisHost;
        this.postgisPort = postgisPort;
        this.postgisDb = postgisDb;
        this.postgisUsername = postgisUsername;
        this.postgisPassword = postgisPassword;
    }
	
	@PostConstruct
    public void ensurePostgisStoreExists() {
    	//TODO replace with non deprecated versions of geosolutions library - requires change in lib version
    	try {
            ensureWorkspaceExists(postgisWorkspace);
        	if (!reader.existsDatastore(postgisWorkspace, postgisStore)) {
                LOG.info("Creating new store {}", postgisStore);
                GSPostGISDatastoreEncoder postgisDataStoreEncoder = new GSPostGISDatastoreEncoder();
                postgisDataStoreEncoder.setName(postgisStore);
                postgisDataStoreEncoder.setHost(postgisHost);
                postgisDataStoreEncoder.setPort(postgisPort);
                postgisDataStoreEncoder.setDatabase(postgisDb);
                postgisDataStoreEncoder.setUser(postgisUsername);
                postgisDataStoreEncoder.setPassword(<PASSWORD>);
                boolean created = publisher.createPostGISDatastore(postgisWorkspace, postgisDataStoreEncoder);
                if (!created) {
                	throw new IngestionException("Cannot create postgis store");
                }
            }
    	}catch(Exception e) {
    	    LOG.error("Cannot ensure availability of postgis store");
    	}
    }

	@Override
    public GeoserverLayer ingest(Path path, GeoServerSpec geoServerSpec, UUID id) {
        String workspace = geoServerSpec.getWorkspace();
        String datastoreName = geoServerSpec.getDatastoreName();
        String coverageName = geoServerSpec.getCoverageName();
        String layerName = geoServerSpec.getLayerName();
        String srs = geoServerSpec.getCrs();
        String style = geoServerSpec.getStyle();
        Map<String, String> options = geoServerSpec.getOptions();
        switch (geoServerSpec.getGeoserverType()) {
            case SINGLE_COVERAGE: 
            	ingestCoverage(workspace, path, srs, datastoreName, coverageName, style);
            	return new GeoserverLayer(null, workspace, datastoreName, coverageName, StoreType.GEOTIFF);
            case MOSAIC: 
            	ingestCoverageInMosaic(workspace, path, datastoreName, coverageName);
            	if (coverageName == null) {<commit_msg>Fix potentially empty map<commit_after>package com.cgi.eoss.fstep.catalogue.geoserver;

import static it.geosolutions.geoserver.rest.encoder.GSResourceEncoder.ProjectionPolicy.REPROJECT_TO_DECLARED;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.cgi.eoss.fstep.catalogue.IngestionException;
import com.cgi.eoss.fstep.catalogue.geoserver.model.GeoserverImportTask;
import com.cgi.eoss.fstep.catalogue.geoserver.model.GeoserverImportTask.UpdateMode;
import com.cgi.eoss.fstep.catalogue.util.GeoUtil;
import com.cgi.eoss.fstep.model.GeoserverLayer;
import com.cgi.eoss.fstep.model.GeoserverLayer.StoreType;
import com.fasterxml.jackson.core.JsonProcessingException;

import it.geosolutions.geoserver.rest.GeoServerRESTManager;
import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
import it.geosolutions.geoserver.rest.GeoServerRESTReader;
import it.geosolutions.geoserver.rest.decoder.RESTCoverageStore;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
import it.geosolutions.geoserver.rest.encoder.GSPostGISDatastoreEncoder;
import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder;
import it.geosolutions.geoserver.rest.encoder.coverage.GSCoverageEncoder;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
import okhttp3.HttpUrl;

@Component
@Log4j2
public class GeoserverServiceImpl implements GeoserverService {

    private static final String RASTER_STYLE = "raster";

    @Getter
    private final HttpUrl externalUrl;
    private final GeoServerRESTPublisher publisher;
    private final GeoServerRESTReader reader;

    @Value("${fstep.catalogue.geoserver.enabled:true}")
    private boolean geoserverEnabled;

    private Set<String> ingestableFiletypes;

    private GeoserverMosaicManager mosaicManager;

	private GeoserverImporter importer;
	
	private String postgisStore;
	
	private String postgisWorkspace;

	private String postgisHost;

	private int postgisPort;

	private String postgisDb;

	private String postgisUsername;

	private String postgisPassword;

	@Autowired
    public GeoserverServiceImpl(@Value("${fstep.catalogue.geoserver.url:http://fstep-geoserver:9080/geoserver/}") String url,
            @Value("${fstep.catalogue.geoserver.externalUrl:http://fstep-geoserver:9080/geoserver/}") String externalUrl,
            @Value("#{'${fstep.catalogue.geoserver.ingest-filetypes:TIF}'.split(',')}") Set<String> ingestableFiletypes,
            @Value("${fstep.catalogue.geoserver.username:fstepgeoserver}") String username,
            @Value("${fstep.catalogue.geoserver.password:<PASSWORD>}") String password,
            @Value("${fstep.catalogue.geoserver.postgisHost:fstepdb}") String postgisHost,
            @Value("${fstep.catalogue.geoserver.postgisPort:5432}") int postgisPort,
            @Value("${fstep.catalogue.geoserver.postgisDb:fstepgeoserver}") String postgisDb,
            @Value("${fstep.catalogue.geoserver.postgisUsername:fstepgeoserverPostgis}") String postgisUsername,
            @Value("${fstep.catalogue.geoserver.postgisPassword:<PASSWORD>}") String postgisPassword,
            @Value("${fstep.catalogue.geoserver.postgisStore:fstepgeoserverPostgisStore}") String postgisStore,
            @Value("${fstep.catalogue.geoserver.postgisWorkspace:fstepgeoserverPostgisWorkspace}") String postgisWorkspace
            ) throws MalformedURLException {
        this.externalUrl = HttpUrl.parse(externalUrl);
        GeoServerRESTManager geoserver = new GeoServerRESTManager(new URL(url), username, password);
        if (ingestableFiletypes == null){
        	ingestableFiletypes = new HashSet<>();
        }
        this.ingestableFiletypes = ingestableFiletypes;
        this.reader = geoserver.getReader();
        this.publisher = geoserver.getPublisher();
        this.importer = new GeoserverImporter(new URL(url), username, password);
        this.mosaicManager = new GeoserverMosaicManager(reader, new URL(url), username, password, postgisHost, postgisPort, postgisDb, postgisUsername, postgisPassword);
        this.postgisStore = postgisStore;
        this.postgisWorkspace = postgisWorkspace;
        this.postgisHost = postgisHost;
        this.postgisPort = postgisPort;
        this.postgisDb = postgisDb;
        this.postgisUsername = postgisUsername;
        this.postgisPassword = <PASSWORD>;
    }
	
	@PostConstruct
    public void ensurePostgisStoreExists() {
    	//TODO replace with non deprecated versions of geosolutions library - requires change in lib version
    	try {
            ensureWorkspaceExists(postgisWorkspace);
        	if (!reader.existsDatastore(postgisWorkspace, postgisStore)) {
                LOG.info("Creating new store {}", postgisStore);
                GSPostGISDatastoreEncoder postgisDataStoreEncoder = new GSPostGISDatastoreEncoder();
                postgisDataStoreEncoder.setName(postgisStore);
                postgisDataStoreEncoder.setHost(postgisHost);
                postgisDataStoreEncoder.setPort(postgisPort);
                postgisDataStoreEncoder.setDatabase(postgisDb);
                postgisDataStoreEncoder.setUser(postgisUsername);
                postgisDataStoreEncoder.setPassword(<PASSWORD>);
                boolean created = publisher.createPostGISDatastore(postgisWorkspace, postgisDataStoreEncoder);
                if (!created) {
                	throw new IngestionException("Cannot create postgis store");
                }
            }
    	}catch(Exception e) {
    	    LOG.error("Cannot ensure availability of postgis store");
    	}
    }

	@Override
    public GeoserverLayer ingest(Path path, GeoServerSpec geoServerSpec, UUID id) {
        String workspace = geoServerSpec.getWorkspace();
        String datastoreName = geoServerSpec.getDatastoreName();
        String coverageName = geoServerSpec.getCoverageName();
        String layerName = geoServerSpec.getLayerName();
        String srs = geoServerSpec.getCrs();
        String style = geoServerSpec.getStyle();
        Map<String, String> options = geoServerSpec.getOptions() != null ? geoServerSpec.getOptions() : Collections.emptyMap();
        switch (geoServerSpec.getGeoserverType()) {
            case SINGLE_COVERAGE: 
            	ingestCoverage(workspace, path, srs, datastoreName, coverageName, style);
            	return new GeoserverLayer(null, workspace, datastoreName, coverageName, StoreType.GEOTIFF);
            case MOSAIC: 
            	ingestCoverageInMosaic(workspace, path, datastoreName, coverageName);
            	if (coverageName == null) {
{'fraction_non_alphanumeric': 0.09477617302579579, 'fraction_numerical': 0.002586764388876913, 'mean_word_length': 4.024548736462094, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '835599', 'n_tokens_mistral': 4329, 'n_tokens_neox': 4199, 'n_words': 684}