package de.duehl.basics.io.textfile.dictionary;

/*
 * Copyright 2024 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import static org.junit.Assert.*;

import java.util.List;

import org.junit.Test;

import de.duehl.basics.collections.CollectionsHelper;

public class DictionaryEntryTest {

    @Test
    public void createFromMainWordAndGetMainWord() {
        String mainWord = "foo";
        DictionaryEntry entry = new DictionaryEntry(mainWord);
        String actual = entry.getMainWord();
        assertEquals(mainWord, actual);
    }

    @Test (expected = IllegalArgumentException.class)
    public void createFromEmptyMainWordFailes() {
        String mainWord = "";
        new DictionaryEntry(mainWord);
    }

    @Test
    public void createFromListWithOnlyMainWordAndGetMainWord() {
        String mainWord = "foo";
        List<String> words = CollectionsHelper.buildListFrom(mainWord);
        DictionaryEntry entry = new DictionaryEntry(words);
        String actual = entry.getMainWord();
        assertEquals(mainWord, actual);
    }

    @Test (expected = IllegalArgumentException.class)
    public void createFromEmtyListFailes() {
        List<String> words = CollectionsHelper.buildListFrom();
        new DictionaryEntry(words);
    }

    @Test
    public void createFromMainWordAndAddAlternativesGetMainWordAndAlternatives() {
        String mainWord = "foo";
        String alternative1 = "bar";
        String alternative2 = "baz";
        DictionaryEntry entry = new DictionaryEntry(mainWord);
        entry.addAlternative(alternative1);
        entry.addAlternative(alternative2);

        String actual = entry.getMainWord();
        assertEquals(mainWord, actual);

        List<String> alternatives = entry.getAlternatives();
        assertEquals(2, alternatives.size());
        assertEquals(alternative1, alternatives.get(0));
        assertEquals(alternative2, alternatives.get(1));
    }

    @Test
    public void createFromMainWordAndAddAlternativesListGetMainWordAndAlternatives() {
        String mainWord = "foo";
        String alternative1 = "bar";
        String alternative2 = "baz";
        List<String> alternatives = CollectionsHelper.buildListFrom(alternative1, alternative2);
        DictionaryEntry entry = new DictionaryEntry(mainWord);
        entry.addAlternatives(alternatives);

        String actual = entry.getMainWord();
        assertEquals(mainWord, actual);

        List<String> actualAlternatives = entry.getAlternatives();
        assertEquals(2, actualAlternatives.size());
        assertEquals(alternative1, actualAlternatives.get(0));
        assertEquals(alternative2, actualAlternatives.get(1));
    }

    @Test
    public void createDescription() {
        String mainWord = "foo";
        String alternative1 = "bar";
        String alternative2 = "baz";
        DictionaryEntry entry = new DictionaryEntry(mainWord);
        entry.addAlternative(alternative1);
        entry.addAlternative(alternative2);

        String actual = entry.createDescription(4);
        String expected = """
                    foo
                        bar
                        baz
                """;
        assertEquals(expected , actual);
    }

    @Test
    public void contains() {
        String mainWord = "foo";
        String alternative1 = "bar";
        String alternative2 = "baz";
        DictionaryEntry entry = new DictionaryEntry(mainWord);
        entry.addAlternative(alternative1);
        entry.addAlternative(alternative2);

        assertTrue(entry.contains("foo"));
        assertTrue(entry.contains("bar"));
        assertTrue(entry.contains("baz"));

        assertFalse(entry.contains("Apfel"));
        assertFalse(entry.contains("blubb"));
    }

    @Test
    public void textContainsMainWordOrAlternative() {
        String mainWord = "Apfel";
        String alternative1 = "Boskop";
        String alternative2 = "Elstar";
        DictionaryEntry entry = new DictionaryEntry(mainWord);
        entry.addAlternative(alternative1);
        entry.addAlternative(alternative2);

        assertTrue(entry.textContainsMainWordOrAlternative("Ein Boskop liegt auf dem Teller"));
        assertTrue(entry.textContainsMainWordOrAlternative("Im Garten steht ein Apfelbaum"));

        assertFalse(entry.textContainsMainWordOrAlternative("Im Garten steht ein Birnbaum"));
    }

    @Test
    public void size() {
        String mainWord = "foo";
        String alternative1 = "bar";
        String alternative2 = "baz";
        DictionaryEntry entry = new DictionaryEntry(mainWord);
        entry.addAlternative(alternative1);
        entry.addAlternative(alternative2);

        assertEquals(3, entry.size());
    }

    @Test
    public void unsortedAlternatives() {
        DictionaryEntry entry = new DictionaryEntry("Baum");
        entry.addAlternative("Eiche");
        entry.addAlternative("Buche");
        entry.addAlternative("Erle");
        entry.addAlternative("Birke");
        entry.addAlternative("Esche");

        assertEquals("Baum", entry.getMainWord());

        List<String> actualAlternatives = entry.getAlternatives();
        assertEquals(5, actualAlternatives.size());
        assertEquals("Eiche", actualAlternatives.get(0));
        assertEquals("Buche", actualAlternatives.get(1));
        assertEquals("Erle", actualAlternatives.get(2));
        assertEquals("Birke", actualAlternatives.get(3));
        assertEquals("Esche", actualAlternatives.get(4));
    }

    @Test
    public void sortAlternatives() {
        DictionaryEntry entry = new DictionaryEntry("Baum");
        entry.addAlternative("Eiche");
        entry.addAlternative("Buche");
        entry.addAlternative("Erle");
        entry.addAlternative("Birke");
        entry.addAlternative("Esche");

        entry.sortAlternatives();

        assertEquals("Baum", entry.getMainWord());

        List<String> actualAlternatives = entry.getAlternatives();
        assertEquals(5, actualAlternatives.size());
        assertEquals("Birke", actualAlternatives.get(0));
        assertEquals("Buche", actualAlternatives.get(1));
        assertEquals("Eiche", actualAlternatives.get(2));
        assertEquals("Erle", actualAlternatives.get(3));
        assertEquals("Esche", actualAlternatives.get(4));
    }

    @Test
    public void addSameMultipleAndGetOneEntry() {
        DictionaryEntry fooEntry = new DictionaryEntry("foo");
        fooEntry.addAlternative("bar");
        fooEntry.addAlternative("bar");

        List<String> alternatives = fooEntry.getAlternatives();
        assertEquals(1, alternatives.size());
        assertEquals("bar", alternatives.get(0));
    }

    @Test
    public void addAllSameMultipleAndGetOneEntry() {
        String mainWord = "foo";
        String alternative1 = "bar";
        String alternative2 = "bar";
        List<String> alternatives = CollectionsHelper.buildListFrom(alternative1, alternative2);

        DictionaryEntry fooEntry = new DictionaryEntry(mainWord);
        fooEntry.addAlternatives(alternatives);


        List<String> alternativesOut = fooEntry.getAlternatives();
        assertEquals(1, alternativesOut.size());
        assertEquals("bar", alternativesOut.get(0));
    }

}
