package org.getopentest.util;

import java.util.List;
import java.util.Map;
import static org.testng.Assert.*;
import org.testng.annotations.Test;

public class ConfigNGTest {

    public ConfigNGTest() {
    }

    @Test
    public void getList() {
        Config config = Config.loadYaml("prop1: { prop2: [123, \"456\"] }");
        List prop2 = config.getList("prop1.prop2");
        assertTrue(prop2.get(0).equals(123));
        assertTrue(prop2.get(1).equals("456"));
    }
    
    @Test
    public void getMap() {
        Config config = Config.loadYaml("prop1: { prop2: { prop3: 123, prop4: \"456\" } }");
        Map prop2 = config.getMap("prop1.prop2");
        assertTrue(prop2.get("prop3").equals(123));
        assertTrue(prop2.get("prop4").equals("456"));
    }
    
    @Test
    public void testGetExistingProperty() {
        Config config = new Config();
        config.set("intValue", 123);
        config.set("stringValue", "123");
        assertEquals(config.get("intValue"), 123);
        assertEquals(config.get("stringValue"), "123");
        assertEquals(config.getInteger("stringValue"), (Integer) 123);
    }

    @Test
    public void testGetMissingProperty() {
        try {
            Config config = new Config();
            config.getString("something");

            fail("No exception was thrown while attempting to read a non-existing property");
        } catch (Exception ex) {
            assertTrue(ex.getMessage().contains("something"));
        }
    }

    @Test
    public void testGetMissingStringPropertyWithNullDefault() {
        try {
            Config config = new Config();
            assertEquals(config.get("something"), null);

            fail("No exception was thrown while attempting to read a non-existing property");
        } catch (Exception ex) {
            assertTrue(ex.getMessage().contains("something"));
        }
    }

    @Test
    public void testHasProperty() {
        Config config = Config.loadYaml("prop1: { prop2: { prop3: 123 } }");
        assertTrue(config.hasProperty("prop1.prop2.prop3"));
        assertFalse(config.hasProperty("prop1.prop2.prop3.prop4"));
    }

    @Test
    public void testHasPropertyOnException() {
        Config config = Config.loadYaml("prop1: { prop2: { prop3: 123 } }");
        assertFalse(config.hasProperty("prop123.prop1"));
    }

    @Test
    public void testLoadPropertiesFile() {
        Config config = Config.load("actor.test.properties");
        assertEquals(config.get("actorType").getClass(), String.class);
    }

    @Test
    public void testLoadYamlFile() {
        Config config = Config.load("actor.test.yaml");
        assertEquals(config.get("actorType").getClass(), String.class);
    }

    @Test
    public void testReadMultiLevelProperty() {
        Config config = Config.loadYaml("prop1: { prop2: { prop3: 123 } }");
        assertEquals(config.get("prop1.prop2.prop3"), 123);
    }

    @Test
    public void testReadMultiLevelPropertyNegative() {

        try {
            Config config = Config.loadYaml("prop1: { prop2: { prop3: 123 } }");
            config.get("prop1.prop2.prop3.prop4");

            fail("No exception was thrown while attempting to read a non-existing property");
        } catch (Exception ex) {
            assertTrue(ex.getCause().getMessage().contains("prop4"));
        }
    }
}
