package org.dainst.chronontology.config;

import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.util.Properties;

import static org.testng.Assert.*;

/**
 * @author Daniel M. de Oliveira
 */
public class AppConfigTest {

    private AppConfig appConfig;
    private Properties props= null;

    @BeforeMethod
    public void before() {
        props= new Properties();
        appConfig= new AppConfig();
    }

    @Test
    public void basic() {
        props.put("serverPort","4567");
        props.put("typeNames","period");
        props.put("credentials","abc:def");

        appConfig.validate(props);
        assertEquals(appConfig.getServerPort(),"4567");
        assertEquals(appConfig.getCredentials()[0],"abc:def");
    }

    /**
     * required: typeNames
     */
    @Test
    public void missingRequiredProperty() {
        props.put("credentials","abc:def");

        assertFalse(appConfig.validate(props));
    }

    @Test
    public void useEmbeddedES() {
        props.put("typeNames","period");
        props.put("credentials","abc:def");
        props.put("useEmbeddedES","true");

        appConfig.validate(props);
        assertNotNull(appConfig.getElasticsearchServerConfig());
    }

    @Test
    public void dontUseEmbeddedESBySettingParamFalse() {
        props.put("useEmbeddedES","false");
        props.put("typeNames","period");
        props.put("credentials","abc:def");

        appConfig.validate(props);
        assertNull(appConfig.getElasticsearchServerConfig());
    }

    /**
     * Omitting param is supported for backward compatibility.
     */
    @Test
    public void dontUseEmbeddedESByOmittingParam() {
        props.put("typeNames","period");
        props.put("credentials","abc:def");
        props.put("useConnect","false");

        assertTrue(appConfig.validate(props));
        assertNull(appConfig.getElasticsearchServerConfig());
    }

    @Test
    public void allowOmitServerPort() {
        props.put("typeNames","period");
        props.put("credentials","abc:def");
        props.put("useEmbeddedES","true");
        props.put("useConnect","false");

        assertTrue(appConfig.validate(props));
        assertEquals(appConfig.getServerPort(), ConfigConstants.SERVER_PORT);
    }


    @Test
    public void elasticSearchServerConfig() {
        props.put("typeNames","period");
        props.put("credentials","abc:def");
        props.put("useEmbeddedES","true");
        props.put("useConnect","false");

        assertTrue(appConfig.validate(props));
        assertEquals(appConfig.getElasticsearchServerConfig().getPort(), ConfigConstants.EMBEDDED_ES_PORT);
    }

    @Test
    public void firstDatastoreNotOfTypeES() {
        props.put("typeNames","period");
        props.put("credentials","abc:def");
        props.put("useEmbeddedES","true");
        props.put("useConnect","false");
        props.put("datastores.0.type",ConfigConstants.DATASTORE_TYPE_FS);

        assertFalse(appConfig.validate(props));
    }

    @Test
    public void controller() {
        props.put("typeNames","period");
        props.put("credentials","abc:def");
        props.put("useEmbeddedES","true");
        props.put("useConnect","true");
        props.put("datastores.1.type","filesystem");

        assertTrue(appConfig.validate(props));
        assertEquals(appConfig.getControllerConfig().isUseConnect(),true);
    }

    @Test
    public void serverPortNotANumber() {
        props.put("serverPort","a7");
        props.put("typeNames","period");
        props.put("credentials","abc:def");

        assertFalse(appConfig.validate(props));
        assertTrue(appConfig.getConstraintViolations().get(0).contains(
                ConfigConstants.MSG_CONSTRAINT_VIOLATION+AppConfig.MSG_SERVER_PORT_NAN));
    }

    @Test
    public void datastore0isNotES() {
        props.put("serverPort","4567");
        props.put("typeNames","period");
        props.put("credentials","abc:def");
        props.put("datastores.0.type","filesystem");

        assertFalse(appConfig.validate(props));
        assertTrue(appConfig.getConstraintViolations().contains(
                ConfigConstants.MSG_CONSTRAINT_VIOLATION+ControllerConfig.MSG_MUST_TYPE_ES));
    }

    @Test
    public void mergeMessagesWithControllerMessages() {
        props.put("serverPort","a7");
        props.put("typeNames","period");
        props.put("credentials","abc:def");
        props.put("datastores.0.type","filesystem");

        assertFalse(appConfig.validate(props));
        assertTrue(appConfig.getConstraintViolations().contains(
                ConfigConstants.MSG_CONSTRAINT_VIOLATION+AppConfig.MSG_SERVER_PORT_NAN+"\"a7\"."));
        assertTrue(appConfig.getConstraintViolations().contains(
                ConfigConstants.MSG_CONSTRAINT_VIOLATION+ControllerConfig.MSG_MUST_TYPE_ES));
    }
}

@@ -2675,361 +2675,8 @@
  %7D%0A%0A
-    @Test%0A    public void firstDatastoreNotOfTypeES() %7B%0A        props.put(%22typeNames%22,%22period%22);%0A        props.put(%22credentials%22,%22abc:def%22);%0A        props.put(%22useEmbeddedES%22,%22true%22);%0A        props.put(%22useConnect%22,%22false%22);%0A        props.put(%22datastores.0.type%22,ConfigConstants.DATASTORE_TYPE_FS);%0A%0A        assertFalse(appConfig.validate(props));%0A    %7D
 %0A%0A  
@@ -3500,16 +3500,23 @@
 0isNotES
+_single
 () %7B%0A   
@@ -3531,33 +3531,34 @@
 ps.put(%22
+u
 se
-rverPort%22,%224567
+Connect%22,%22false
 %22);%0A    
@@ -3576,38 +3576,72 @@
 ut(%22
-typeNames%22,%22period%22
+datastores.0.type%22,ConfigConstants.DATASTORE_TYPE_FS
 );%0A
+%0A
         
 prop
@@ -3640,43 +3640,269 @@
     
-props.put(%22credentials%22,%22abc:def%22);
+assertFalse(appConfig.validate(props));%0A        assertTrue(appConfig.getConstraintViolations().contains(%0A                ConfigConstants.MSG_CONSTRAINT_VIOLATION+ControllerConfig.MSG_MUST_TYPE_ES));%0A    %7D%0A%0A    @Test%0A    public void datastore0isNotES_connect() %7B
 %0A   

Make tests more concise.