/*
 * Copyright (c) 2013, Luigi R. Viggiano
 * All rights reserved.
 *
 * This software is distributable under the BSD license.
 * See the terms of the BSD license in the documentation provided with this software.
 */

package org.aeonbits.owner;

import org.aeonbits.owner.Config.Sources;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.util.Properties;

import static org.aeonbits.owner.UtilTest.save;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

/**
 * @author Luigi R. Viggiano
 */
public class ConfigFactoryTest implements TestConstants {

    @Sources("file:${mypath}/myconfig.properties")
    interface MyConfig extends Config {
        @DefaultValue("defaultValue")
        String someValue();
    }

    @Before
    public void before() throws IOException {
        ConfigFactory.setProperties(new Properties());
        save(new File(RESOURCES_DIR + "/myconfig.properties"), new Properties() {{
            setProperty("someValue", "foobar");
        }});
    }

    @Test
    public void testSetProperty()  {
        ConfigFactory.setProperty("mypath", RESOURCES_DIR);

        MyConfig cfg = ConfigFactory.create(MyConfig.class);

        assertEquals("foobar", cfg.someValue());
    }

    @Test(expected = NullPointerException.class)
    public void testSetPropertyNullKey() {
        ConfigFactory.setProperty(null, "foobar");
    }

    @Test(expected = IllegalArgumentException.class)
    public void testSetPropertyEmptyKey() {
        ConfigFactory.setProperty("", "foobar");
    }

    @Test
    public void testSetPropertyTwice()  {
        assertNull(ConfigFactory.setProperty("mypath", RESOURCES_DIR));
        assertEquals(RESOURCES_DIR, ConfigFactory.setProperty("mypath", RESOURCES_DIR + "-2"));
        assertEquals(RESOURCES_DIR + "-2", ConfigFactory.getProperty("mypath"));
    }

    @Test
    public void testGetProperties() {
        ConfigFactory.getProperties().setProperty("mypath", RESOURCES_DIR);

        MyConfig cfg = ConfigFactory.create(MyConfig.class);

        assertEquals("foobar", cfg.someValue());
    }

    @Test
    public void testSetProperties() {
        ConfigFactory.setProperties(new Properties() {{
            setProperty("mypath", RESOURCES_DIR);
        }});

        MyConfig cfg = ConfigFactory.create(MyConfig.class);

        assertEquals("foobar", cfg.someValue());
    }

    @Test
    public void testSetPropertiesNullObject() {
        ConfigFactory.setProperties(null);

        MyConfig cfg = ConfigFactory.create(MyConfig.class);

        assertEquals("defaultValue", cfg.someValue());
    }

    @Test
    public void testGetProperty() {
        ConfigFactory.setProperty("mypath", RESOURCES_DIR);
        assertEquals(RESOURCES_DIR, ConfigFactory.getProperty("mypath"));
    }

    @Test(expected = NullPointerException.class)
    public void testGetPropertyNullKey() {
        ConfigFactory.getProperty(null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testGetPropertiesEmptyKey() {
        ConfigFactory.getProperty("");
    }

    @Test
    public void testGetClearProperty() {
        ConfigFactory.setProperty("mypath", RESOURCES_DIR);
        assertEquals(RESOURCES_DIR, ConfigFactory.clearProperty("mypath"));
        assertNull(ConfigFactory.getProperty("mypath"));
    }

    @Test(expected = NullPointerException.class)
    public void testClearPropertyNullKey() {
        ConfigFactory.clearProperty(null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testClearPropertyEmptyKey() {
        ConfigFactory.clearProperty("");
    }

}

@@ -3678,10 +3678,516 @@
 %0A    %7D%0A%0A
+    @Sources(%22$%7Bmyurl%7D%22)%0A    interface MyConfigWithoutProtocol extends Config %7B%0A        @DefaultValue(%22defaultValue%22)%0A        String someValue();%0A    %7D%0A%0A    @Test%0A    public void testSetPropertyWithoutProtocol()  %7B%0A        ConfigFactory.setProperty(%22mypath%22, RESOURCES_DIR);%0A        ConfigFactory.setProperty(%22myurl%22, %22file:$%7Bmypath%7D/myconfig.properties%22);%0A%0A        MyConfigWithoutProtocol cfg = ConfigFactory.create(MyConfigWithoutProtocol.class);%0A%0A        assertEquals(%22foobar%22, cfg.someValue());%0A    %7D%0A%0A
 %7D%0A

test expansion of @Sources urls when no protocol is specified