package org.codehaus.mojo.properties;

import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.yaml.snakeyaml.composer.ComposerException;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class YamlToPropertiesConverterTest {

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Rule
    public TemporaryFolder folder = new TemporaryFolder();

    private File file;

    @Before
    public void setUp()
            throws Exception {
        file = folder.newFile("test.yml");
    }

    @Test
    public void testConvertToProperties()
            throws Exception {
        // Arrange
        final List<String> lines = Arrays.asList(
                "---",
                "this.is.a.standard.property: this is the value",
                "a: #This comment shouldn't appear",
                "   hierarchical:",
                "       property1: yet another value",
                "       property2: the last value",
                "list:",
                "   -list value1",
                "   -list value2", "anotherkey:",
                "    { nestedkey1: value1, nestedkey2: value2 }",
                "list2:",
                "   - map_key: map_value",
                "...");
        FileUtils.writeLines(file, lines);

        final InputStream inputStream = new FileInputStream(file);

        // Act
        final Properties properties = YamlToPropertiesConverter.convertToProperties(inputStream);

        // Assert
        assertEquals("Six keys are expected", properties.keySet().size(), 7);

        assertTrue(properties.keySet().contains("this.is.a.standard.property"));
        assertTrue(properties.getProperty("this.is.a.standard.property").equals("this is the value"));

        assertTrue(properties.keySet().contains("a.hierarchical.property1"));
        assertTrue(properties.getProperty("a.hierarchical.property1").equals("yet another value"));
        assertTrue(properties.keySet().contains("a.hierarchical.property2"));
        assertTrue(properties.getProperty("a.hierarchical.property2").equals("the last value"));

        assertTrue(properties.keySet().contains("list"));
        assertTrue(properties.getProperty("list").equals("-list value1 -list value2"));

        assertTrue(properties.keySet().contains("anotherkey.nestedkey1"));
        assertTrue(properties.getProperty("anotherkey.nestedkey1").equals("value1"));
        assertTrue(properties.keySet().contains("anotherkey.nestedkey2"));
        assertTrue(properties.getProperty("anotherkey.nestedkey2").equals("value2"));
        assertTrue(properties.keySet().contains("list2.map_key"));
        assertTrue(properties.getProperty("list2.map_key").equals("map_value"));
    }

    @Test
    public void testConvertToPropertiesIgnoreComments()
            throws Exception {
        // Arrange
        final List<String> lines = Arrays.asList(
                "this.is.a.standard.property: this is the value",
                "#A very helpful comment",
                "a:",
                "   hierarchical:",
                "       property: yet another value");
        FileUtils.writeLines(file, lines);

        final InputStream inputStream = new FileInputStream(file);

        // Act
        final Properties properties = YamlToPropertiesConverter.convertToProperties(inputStream);

        // Assert
        assertEquals("Two keys are expected", properties.keySet().size(), 2);

        assertTrue(properties.keySet().contains("this.is.a.standard.property"));
        assertTrue(properties.getProperty("this.is.a.standard.property").equals("this is the value"));

        assertTrue(properties.keySet().contains("a.hierarchical.property"));
        assertTrue(properties.getProperty("a.hierarchical.property").equals("yet another value"));
    }

    @Test
    public void testConvertToPropertiesFailsOnNewDocument()
            throws Exception {
        // Arrange
        thrown.expect(ComposerException.class);

        final List<String> lines = Arrays.asList(
                "---",
                "this.is.a.standard.property: this is the value",
                "a:",
                "...",
                "---",
                "   hierarchical:",
                "       property: yet another value",
                "...");
        FileUtils.writeLines(file, lines);

        final InputStream inputStream = new FileInputStream(file);

        // Act
        YamlToPropertiesConverter.convertToProperties(inputStream);

        // Assert
        fail("Expected an exception because of multiple documents in the same Yaml file");
    }

}

@@ -1571,32 +1571,62 @@
 ey: map_value%22,%0A
+                %22empty_key:%22,%0A
                 
@@ -1903,11 +1903,13 @@
 ls(%22
-Six
+Eight
  key
@@ -1957,9 +1957,9 @@
 (), 
-7
+8
 );%0A%0A
@@ -3106,32 +3106,100 @@
 (%22map_value%22));%0A
+        assertTrue(properties.getProperty(%22empty_key%22).equals(%22%22));%0A
     %7D%0A%0A    @Test

adding test case for key with empty value - value should be "" not null