/*
 * The MIT License (MIT)
 * Copyright (c) 2017 Nicholas Wright
 * http://opensource.org/licenses/MIT
 */
package com.github.dozedoff.commonj.settings;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;

import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class AbstractSettingsTest {
	private ISettingsValidator validator;
	private AbstractSettings abstractSettings;
	private static Properties testProperties;
	private static Path propertiesPath;
	private static Path filename;

	private static final String TEST_KEY = "test";

	@BeforeClass
	public static void classSetup() throws Exception {
		testProperties = new Properties();
		testProperties.put(TEST_KEY, Integer.toString(42));

		propertiesPath = Files.createTempFile(AbstractSettingsTest.class.getCanonicalName(), "properties");
		filename = propertiesPath.getFileName();

		Files.newOutputStream(propertiesPath);

		testProperties.store(Files.newOutputStream(propertiesPath), "");
	}

	@AfterClass
	public static void classTearDown() throws Exception {
		Files.deleteIfExists(propertiesPath);
	}

	@Before
	public void setup() {
		validator = mock(ISettingsValidator.class);
		abstractSettings = new AbstractSettings(validator) {
		};
	}

	@Test
	public void testLoadPropertiesNoFile() throws Exception {
		abstractSettings.loadPropertiesFromFile("foo");
		assertThat(abstractSettings.properties.isEmpty(), is(true));
	}

	@Test
	public void testLoadPropertiesFromFileString() throws Exception {
		abstractSettings.loadPropertiesFromFile(propertiesPath.toString());
		assertThat(abstractSettings.properties.containsKey(TEST_KEY), is(true));
	}

	@Test
	public void testLoadPropertiesFromFilePathString() throws Exception {
		abstractSettings.loadPropertiesFromFile(propertiesPath.getParent(), filename.toString());
		assertThat(abstractSettings.properties.containsKey(TEST_KEY), is(true));
	}

	@Test
	public void testLoadPropertiesFromFileAbsolute() throws Exception {
		abstractSettings.loadPropertiesFromFileAbsolute(propertiesPath);
		assertThat(abstractSettings.properties.containsKey(TEST_KEY), is(true));
	}

	@Test(expected = UnsupportedOperationException.class)
	public void testValidateSettingsNoValidator() throws Exception {
		abstractSettings = new AbstractSettings(null) {
		};
		abstractSettings.validateSettings();
	}

	@Test
	public void testValidateSettingsValid() throws Exception {
		when(validator.validate(abstractSettings)).thenReturn(true);
		assertThat(abstractSettings.validateSettings(), is(true));
	}

	@Test
	public void testSaveSettings() throws Exception {
		abstractSettings.loadPropertiesFromFileAbsolute(propertiesPath);
		abstractSettings.properties.put("foo", "bar");
		abstractSettings.saveSettings();

		AbstractSettings as = new AbstractSettings(validator) {
		};

		// guard
		assertThat(as.properties.containsKey("foo"), is(false));
		as.loadPropertiesFromFileAbsolute(propertiesPath);

		assertThat(as.properties.containsKey("foo"), is(true));
	}
}

@@ -312,16 +312,73 @@
 .when;%0A%0A
+import java.io.IOException;%0Aimport java.io.OutputStream;%0A
 import j
@@ -955,16 +955,156 @@
  %22test%22;
+%0A%09private static final String TEST_KEY_UNKNOWN = %22foo%22;%0A%0A%09private static OutputStream outStream;%0A%0A%09private static final int TEST_VALUE = 42;
 %0A%0A%09@Befo
@@ -1248,18 +1248,26 @@
 oString(
-42
+TEST_VALUE
 ));%0A%0A%09%09p
@@ -1411,16 +1411,28 @@
 e();%0A%0A%09%09
+outStream = 
 Files.ne
@@ -1490,45 +1490,17 @@
 ore(
-Files.newOutputStream(propertiesPath)
+outStream
 , %22%22
@@ -1574,16 +1574,37 @@
 ption %7B%0A
+%09%09outStream.close();%0A
 %09%09Files.
@@ -1664,17 +1664,17 @@
 void set
-u
+U
 p() %7B%0A%09%09
@@ -1889,21 +1889,32 @@
 romFile(
-%22foo%22
+TEST_KEY_UNKNOWN
 );%0A%09%09ass

Test cleanup