package de.duehl.basics.collections;

/*
 * 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.text.Text;

public class StringListComparerTest {

    @Test
    public void compareEmptyLists() {
        List<String> list1 = CollectionsHelper.buildListFrom();
        List<String> list2 = CollectionsHelper.buildListFrom();

        StringListComparer comparer = new StringListComparer(list1, list2);
        comparer.compare();
        assertTrue(comparer.isEqual());
        assertEquals("", comparer.getNotEqualReason());
    }

    @Test
    public void compareListsWithEqualElements() {
        List<String> list1 = CollectionsHelper.buildListFrom("a", "b", "c");
        List<String> list2 = CollectionsHelper.buildListFrom("a", "b", "c");

        StringListComparer comparer = new StringListComparer(list1, list2);
        comparer.compare();
        assertTrue(comparer.isEqual());
        assertEquals("", comparer.getNotEqualReason());
    }

    @Test
    public void compareEmptyListAgainstFilledList() {
        List<String> list1 = CollectionsHelper.buildListFrom();
        List<String> list2 = CollectionsHelper.buildListFrom("a");

        StringListComparer comparer = new StringListComparer(list1, list2);
        comparer.compare();
        assertFalse(comparer.isEqual());
        assertEquals("Die beiden Listen haben unterschiedlich viele Elemente. In der ersten "
                + "Liste sind 0 Elemente und in der zweiten Liste ist 1 Element.",
                comparer.getNotEqualReason());
    }

    @Test
    public void compareFilledListAgainstEmptyList() {
        List<String> list1 = CollectionsHelper.buildListFrom("a");
        List<String> list2 = CollectionsHelper.buildListFrom();

        StringListComparer comparer = new StringListComparer(list1, list2);
        comparer.compare();
        assertFalse(comparer.isEqual());
        assertEquals("Die beiden Listen haben unterschiedlich viele Elemente. In der ersten Liste "
                + "ist 1 Element und in der zweiten Liste sind 0 Elemente.",
                comparer.getNotEqualReason());
    }

    @Test
    public void compareEmptyListAgainstFilledListWithDescription() {
        List<String> list1 = CollectionsHelper.buildListFrom();
        List<String> list2 = CollectionsHelper.buildListFrom("a");

        StringListComparer comparer = new StringListComparer(list1, list2);
        comparer.setDescription1("in der Liste aus Datei a.txt");
        comparer.setDescription2("in der Liste aus Datei b.txt");
        comparer.compare();
        assertFalse(comparer.isEqual());
        assertEquals("Die beiden Listen haben unterschiedlich viele Elemente. "
                + "In in der Liste aus Datei a.txt sind 0 Elemente und in in der Liste aus "
                + "Datei b.txt ist 1 Element.",
                comparer.getNotEqualReason());
    }

    @Test
    public void compareFilledListAgainstEmptyListWithDescription() {
        List<String> list1 = CollectionsHelper.buildListFrom("a");
        List<String> list2 = CollectionsHelper.buildListFrom();

        StringListComparer comparer = new StringListComparer(list1, list2);
        comparer.setDescription1("in der Liste aus Datei a.txt");
        comparer.setDescription2("in der Liste aus Datei b.txt");
        comparer.compare();
        assertFalse(comparer.isEqual());
        assertEquals("Die beiden Listen haben unterschiedlich viele Elemente. In in der Liste aus "
                + "Datei a.txt ist 1 Element und in in der Liste aus Datei b.txt sind 0 Elemente.",
                comparer.getNotEqualReason());
    }

    @Test
    public void compareListsWithEqualSizeButDifferentContent1() {
        List<String> list1 = CollectionsHelper.buildListFrom("a", "b", "c");
        List<String> list2 = CollectionsHelper.buildListFrom("a", "B", "c");

        StringListComparer comparer = new StringListComparer(list1, list2);
        comparer.compare();
        assertFalse(comparer.isEqual());
        assertEquals("Es ist 1 Element in der ersten Liste nicht in der zweiten Liste enthalten:\n"
                + "     1. [B]" + Text.LINE_BREAK + "\n"
                + "Außerdem ist 1 Element in der zweiten Liste nicht in der ersten Liste enthalten:\n"
                + "     1. [b]" + Text.LINE_BREAK,
                comparer.getNotEqualReason());
    }

    @Test
    public void compareListsWithEqualSizeButDifferentContent2a() {
        List<String> list1 = CollectionsHelper.buildListFrom("a", "b", "c");
        List<String> list2 = CollectionsHelper.buildListFrom("a", "b", "a");

        StringListComparer comparer = new StringListComparer(list1, list2);
        comparer.compare();
        assertFalse(comparer.isEqual());
        assertEquals("Es ist 1 Element in der zweiten Liste nicht in der ersten Liste enthalten:\n"
                + "     1. [c]" + Text.LINE_BREAK,
                comparer.getNotEqualReason());
    }

    @Test
    public void compareListsWithEqualSizeButDifferentContent2b() {
        List<String> list1 = CollectionsHelper.buildListFrom("a", "b", "a");
        List<String> list2 = CollectionsHelper.buildListFrom("a", "b", "c");

        StringListComparer comparer = new StringListComparer(list1, list2);
        comparer.compare();
        assertFalse(comparer.isEqual());
        assertEquals("Es ist 1 Element in der ersten Liste nicht in der zweiten Liste enthalten:\n"
                + "     1. [c]" + Text.LINE_BREAK,
                comparer.getNotEqualReason());
    }

    @Test
    public void compareListsWithWrongOrder() {
        List<String> list1 = CollectionsHelper.buildListFrom("a", "b", "c");
        List<String> list2 = CollectionsHelper.buildListFrom("a", "c", "b");

        StringListComparer comparer = new StringListComparer(list1, list2);
        comparer.compare();
        assertFalse(comparer.isEqual());
        assertEquals("An den folgenden Positionen (1-basiert) weichen die beiden Listen von "
                + "einander ab:\n"
                + "    2: 'b' <-> 'c'\n"
                + "    3: 'c' <-> 'b'\n",
                comparer.getNotEqualReason());
    }

}
