package com.fwdekker.randomness.word;

import com.intellij.openapi.ui.ValidationInfo;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.logging.Logger;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.fail;


/**
 * Unit tests for {@link Dictionary.UserDictionary}.
 */
public final class UserDictionaryTest {
    private File dictionaryFile;
    private Dictionary dictionary;


    @Before
    public void beforeEach() throws IOException {
        dictionaryFile = new File("test/test.dic");
        final File dictionaryDirectory = dictionaryFile.getParentFile();

        if (!dictionaryDirectory.exists() && !dictionaryDirectory.mkdirs()) {
            fail("Failed to set up test directory.");
        }
        if (!dictionaryFile.createNewFile()) {
            fail("Failed to set up test file.");
        }

        Files.write(dictionaryFile.toPath(), "Spanners\nHeralds\nTree".getBytes(StandardCharsets.UTF_8));
    }

    @After
    public void afterEach() {
        final File dictionaryDirectory = dictionaryFile.getParentFile();

        if (dictionaryFile.exists() && !dictionaryFile.delete()) {
            Logger.getLogger(getClass().getName()).warning("Failed to clean up test files.");
        } else if (dictionaryDirectory.exists() && !dictionaryDirectory.delete()) {
            Logger.getLogger(getClass().getName()).warning("Failed to clean up test directory.");
        }
    }


    @Test
    public void testInvalidFile() {
        assertThatThrownBy(() -> Dictionary.UserDictionary.get("invalid_file"))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessage("Failed to read dictionary into memory.")
                .hasCauseInstanceOf(IOException.class);
    }

    @Test
    public void testValidateSuccess() {
        dictionary = Dictionary.UserDictionary.get(dictionaryFile.getAbsolutePath());

        final ValidationInfo validationInfo = dictionary.validate();

        assertThat(validationInfo).isNull();
    }

    @Test
    public void testValidateFileDoesNotExist() {
        dictionary = Dictionary.UserDictionary.get(dictionaryFile.getAbsolutePath());

        if (!dictionaryFile.delete()) {
            fail("Failed to delete test file as part of test.");
        }

        final ValidationInfo validationInfo = dictionary.validate();

        assertThat(validationInfo).isNotNull();
        assertThat(validationInfo.message).isEqualTo("The dictionary file for test.dic no longer exists.");
        assertThat(validationInfo.component).isNull();
    }

    @Test
    public void testToString() {
        dictionary = Dictionary.UserDictionary.get(dictionaryFile.getAbsolutePath());

        assertThat(dictionary.toString()).isEqualTo("[custom] test.dic");
    }
}

@@ -83,57 +83,8 @@
 fo;%0A
-import org.junit.After;%0Aimport org.junit.Before;%0A
 impo
@@ -225,41 +225,8 @@
 les;
-%0Aimport java.util.logging.Logger;
 %0A%0Aim
@@ -506,1104 +506,8 @@
 t %7B%0A
-    private File dictionaryFile;%0A    private Dictionary dictionary;%0A%0A%0A    @Before%0A    public void beforeEach() throws IOException %7B%0A        dictionaryFile = new File(%22test/test.dic%22);%0A        final File dictionaryDirectory = dictionaryFile.getParentFile();%0A%0A        if (!dictionaryDirectory.exists() && !dictionaryDirectory.mkdirs()) %7B%0A            fail(%22Failed to set up test directory.%22);%0A        %7D%0A        if (!dictionaryFile.createNewFile()) %7B%0A            fail(%22Failed to set up test file.%22);%0A        %7D%0A%0A        Files.write(dictionaryFile.toPath(), %22Spanners%5CnHeralds%5CnTree%22.getBytes(StandardCharsets.UTF_8));%0A    %7D%0A%0A    @After%0A    public void afterEach() %7B%0A        final File dictionaryDirectory = dictionaryFile.getParentFile();%0A%0A        if (dictionaryFile.exists() && !dictionaryFile.delete()) %7B%0A            Logger.getLogger(getClass().getName()).warning(%22Failed to clean up test files.%22);%0A        %7D else if (dictionaryDirectory.exists() && !dictionaryDirectory.delete()) %7B%0A            Logger.getLogger(getClass().getName()).warning(%22Failed to clean up test directory.%22);%0A        %7D%0A    %7D%0A%0A%0A
     
@@ -873,32 +873,130 @@
 ess() %7B%0A        
+final File dictionaryFile = setUpDictionary(%22Bbls%5CnOverpray%5CnTreeward%22);%0A        final Dictionary 
 dictionary = Dic
@@ -1239,32 +1239,130 @@
 ist() %7B%0A        
+final File dictionaryFile = setUpDictionary(%22Loafer%5CnAquavit%5CnSpahees%22);%0A        final Dictionary 
 dictionary = Dic
@@ -1701,25 +1701,23 @@
 essage).
-isEqualTo
+matches
 (%22The di
@@ -1734,24 +1734,18 @@
 ile for 
-test.dic
+.*
  no long
@@ -1753,16 +1753,18 @@
 r exists
+%5C%5C
 .%22);%0A   
@@ -1873,16 +1873,117 @@
         
+final File dictionaryFile = setUpDictionary(%22Cholers%5CnJaloused%5CnStopback%22);%0A        final Dictionary 
 dictiona
@@ -2099,39 +2099,818 @@
 ()).
-isEqualTo(%22%5Bcustom%5D test.dic%22);
+matches(%22%5C%5C%5Bcustom%5C%5C%5D .*%5C%5C.dic%22);%0A    %7D%0A%0A%0A    /**%0A     * Creates a temporary dictionary file with the given contents.%0A     * %3Cp%3E%0A     * Because the created file is a temporary file, it does not have to be cleaned up afterwards.%0A     *%0A     * @param contents the contents to write to the dictionary file%0A     * @return the created temporary dictionary file%0A     */%0A    private File setUpDictionary(final String contents) %7B%0A        final File dictionaryFile;%0A%0A        try %7B%0A            dictionaryFile = File.createTempFile(%22dictionary%22, %22.dic%22);%0A            Files.write(dictionaryFile.toPath(), contents.getBytes(StandardCharsets.UTF_8));%0A%0A            return dictionaryFile;%0A        %7D catch (final IOException e) %7B%0A            fail(%22Could not set up dictionary file.%22);%0A            return new File(%22%22);%0A        %7D
 %0A   

Restructure dictionary test file setup