package no.deichman.services.services.search;

import no.deichman.services.testutil.PortSelector;
import org.apache.commons.io.FileUtils;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.CloseableHttpClient;
import pl.allegro.tech.embeddedelasticsearch.EmbeddedElastic;
import pl.allegro.tech.embeddedelasticsearch.IndexSettings;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import static java.lang.ClassLoader.getSystemResourceAsStream;
import static java.lang.System.getenv;
import static org.apache.http.impl.client.HttpClients.createDefault;

/**
 * Responsibility: An embedded elasticsearch server for test purposes.
 */
public final class EmbeddedElasticsearchServer {
    private static final String DEFAULT_DATA_DIRECTORY = "/var/tmp/target/elasticsearch-data";
    private static EmbeddedElastic embeddedElastic;
    private final String dataDirectory;
    private static int port;

    public EmbeddedElasticsearchServer() throws Exception {
        this(DEFAULT_DATA_DIRECTORY);
    }

    private EmbeddedElasticsearchServer(String dataDirectory) throws Exception {
        this.dataDirectory = dataDirectory;
        this.port = PortSelector.randomFree();
        new File(dataDirectory).mkdirs();

        IndexSettings idx = IndexSettings.builder()
                        .withSettings(getSystemResourceAsStream("search_index.json"))
                        .withType("person", getSystemResourceAsStream("person_mapping.json"))
                        .withType("publication", getSystemResourceAsStream("publication_mapping.json"))
                        .withType("work", getSystemResourceAsStream("work_mapping.json"))
                        .withType("corporation", getSystemResourceAsStream("corporation_mapping.json"))
                        .withType("serial", getSystemResourceAsStream("serial_mapping.json"))
                        .withType("workSeries", getSystemResourceAsStream("workSeries_mapping.json"))
                        .withType("subject", getSystemResourceAsStream("subject_mapping.json"))
                        .withType("genre", getSystemResourceAsStream("genre_mapping.json"))
                        .withType("instrument", getSystemResourceAsStream("instrument_mapping.json"))
                        .withType("compositionType", getSystemResourceAsStream("compositionType_mapping.json"))
                        .withType("event", getSystemResourceAsStream("event_mapping.json"))
                        .build();

        embeddedElastic = EmbeddedElastic.builder()
                .withElasticVersion("5.4.1")
                .withSetting("http.port", port)
                .withSetting("http.enabled", "true")
                .withSetting("path.home", ".")
                .withSetting("path.data", dataDirectory)
                .withSetting("cluster.name", "test")
                .withStartTimeout(2, TimeUnit.MINUTES)
                .withEsJavaOpts("-Xms512m -Xmx512m")
                .withPlugin(getenv().getOrDefault("ES_ICU_PLUGIN_URL", "analysis-icu"))
                .withIndex("a", idx)
                .withIndex("b", idx)
                .build()
                .start();

        try (CloseableHttpClient httpclient = createDefault()) {
            httpclient.execute(new HttpPut("http://localhost:" + embeddedElastic.getHttpPort() + "/a/_alias/search"));
        }
    }

    public static EmbeddedElastic getClient() {
        return embeddedElastic;
    }


    public static Integer getPort() {
        return port;
    }

    public void shutdown() throws Exception {
        embeddedElastic.stop();
        deleteDataDirectory();
    }

    @Override
    protected void finalize() throws Throwable {
        deleteDataDirectory();
        super.finalize();
    }

    private void deleteDataDirectory() {
        try {
            FileUtils.deleteDirectory(new File(dataDirectory));
        } catch (IOException e) {
            throw new RuntimeException("Could not delete data directory of embedded elasticsearch server", e);
        }
    }
}

@@ -1235,24 +1235,193 @@
 ndomFree();%0A
+        File dataDirectoryFile = new File(dataDirectory);%0A        if (dataDirectoryFile.exists()) %7B%0A            FileUtils.deleteDirectory(dataDirectoryFile);%0A        %7D%0A%0A
         new 
@@ -1515,32 +1515,24 @@
             
-  
-      
 .withSetting
@@ -1577,32 +1577,24 @@
 dex.json%22))%0A
-        
             
@@ -1679,32 +1679,24 @@
             
-   
-     
 .withType(%22p
@@ -1775,32 +1775,24 @@
             
-        
 .withType(%22w
@@ -1857,32 +1857,24 @@
             
-    
-    
 .withType(%22c
@@ -1953,32 +1953,24 @@
             
-        
 .withType(%22s
@@ -2039,32 +2039,24 @@
             
-     
-   
 .withType(%22w
@@ -2133,32 +2133,24 @@
             
-        
 .withType(%22s
@@ -2221,32 +2221,24 @@
             
-      
-  
 .withType(%22g
@@ -2289,32 +2289,24 @@
 ing.json%22))%0A
-        
             
@@ -2399,32 +2399,24 @@
             
-       
- 
 .withType(%22c
@@ -2503,32 +2503,24 @@
             
-        
 .withType(%22e
@@ -2571,32 +2571,24 @@
 ing.json%22))%0A
-        
             
@@ -2957,16 +2957,102 @@
 %22test%22)%0A
+                .withSetting(%22discovery.zen.ping.unicast.hosts%22, %22localhost:%22 + port)%0A
         

remove possible left-behinds from embedded ES that cause Macs to choke, disable multicast