package de.duehl.basics.replacements;

/*
 * 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 java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.junit.Test;

import de.duehl.basics.collections.CollectionsHelper;

public class ReplacementHelperTest {

    @Test
    public void matcherGroupWithPositionToListElement() {
        List<String> obststuecke = CollectionsHelper.buildListFrom("Apfel", "Birne");
        List<String> tische = CollectionsHelper.buildListFrom("Küchentisch");
        String regex = "Der <<obst:1>> und die <<obst:2>> liegen auf dem <<tisch:1>>.";
        Pattern pattern = Pattern.compile("<<obst:(\\d+)>> .* <<obst:(\\d+)>> .* <<tisch:(\\d+)>>");
        Matcher matcher = pattern.matcher(regex);
        matcher.find();
        String obst1 = ReplacementHelper.matcherGroupWithPositionToListElement(matcher, 1, obststuecke);
        String obst2 = ReplacementHelper.matcherGroupWithPositionToListElement(matcher, 2, obststuecke);
        String tisch1 = ReplacementHelper.matcherGroupWithPositionToListElement(matcher, 1, tische);
        assertEquals("Apfel", obst1);
        assertEquals("Birne", obst2);
        assertEquals("Küchentisch", tisch1);
    }

    @Test
    public void determinePlaceholderEndIndex() {
        String text = "foo <<begriff:142>> bar";
        int placeholderStartIndex = 4;
        int actual = ReplacementHelper.determinePlaceholderEndIndex(text, placeholderStartIndex);
        int expected = 19;
        assertEquals(expected, actual);
    }

    @Test
    public void determinePlaceholderPosition() {
        String placeholder = "<<begriff:142>>";
        int actual = ReplacementHelper.determinePlaceholderPosition(placeholder);
        int expected = 142;
        assertEquals(expected, actual);
    }

    @Test
    public void determinePlaceholderPositionWithOutColon() {
        String placeholder = "<<begriff;142>>";
        assertThrows(RuntimeException.class, () ->
            ReplacementHelper.determinePlaceholderPosition(placeholder)
        );
    }

    @Test
    public void determinePlaceholderPositionEndBeforeColon() {
        String placeholder = "<<begriff>>:142";
        assertThrows(RuntimeException.class, () ->
            ReplacementHelper.determinePlaceholderPosition(placeholder)
        );
    }

    @Test
    public void determinePlaceholderPositionIsNotANumber() {
        String placeholder = "<<begriff:1A2>>";
        assertThrows(RuntimeException.class, () ->
            ReplacementHelper.determinePlaceholderPosition(placeholder)
        );
    }

    @Test
    public void searchStartIndexToEndIndexOfPlaceholder() {
        String text = "foo <<begriff:142>> bar";
        int placeholderEndIndex = 19;
        int actual = ReplacementHelper.searchStartIndexToEndIndexOfPlaceholder(text,
                placeholderEndIndex);
        int expected = 4;
        assertEquals(expected, actual);
    }

    @Test
    public void searchStartIndexToEndIndexOfPlaceholderEndsNotAtIndex() {
        String text = "foo <<begriff:142>> bar";
        int placeholderEndIndex = 20;
        assertThrows(RuntimeException.class, () ->
            ReplacementHelper.searchStartIndexToEndIndexOfPlaceholder(text,
                    placeholderEndIndex)
        );
    }

    @Test
    public void endsTextWithPlaceholder() {
        String text = "foo <<begriff:142>> bar";
        assertTrue(ReplacementHelper.endsTextWithPlaceholder(text, 19, "begriff"));
    }

    @Test
    public void endsTextWithPlaceholderWrongIndex() {
        String text = "foo <<begriff:142>> bar";
        assertFalse(ReplacementHelper.endsTextWithPlaceholder(text, 20, "begriff"));
    }

    @Test
    public void endsTextWithPlaceholderWrongIndex2() {
        String text = "foo <<begriff:142>> bar";
        assertFalse(ReplacementHelper.endsTextWithPlaceholder(text, 18, "begriff"));
    }

    @Test
    public void endsTextWithPlaceholderWrongFrontPart() {
        String text = "foo <<begriff:142>> bar";
        assertFalse(ReplacementHelper.endsTextWithPlaceholder(text, 19, "begriffe"));
    }

    @Test
    public void endsTextWithPlaceholderNotAPlaceholderAtAll() {
        String text = "foo la la la la laa bar";
        assertFalse(ReplacementHelper.endsTextWithPlaceholder(text, 18, "begriff"));
    }

    @Test
    public void determinePlaceholderFrontPart() {
        String placeholder = "<<begriff:142>>";
        String actual = ReplacementHelper.determinePlaceholderFrontPart(placeholder);
        String expected = "begriff";
        assertEquals(expected, actual);
    }

    @Test
    public void determinePlaceholderFrontPartWithOutColon() {
        String placeholder = "<<begriff;142>>";
        assertThrows(RuntimeException.class, () ->
            ReplacementHelper.determinePlaceholderFrontPart(placeholder)
        );
    }

    @Test
    public void determinePlaceholderNotStartingCorrect() {
        String placeholder = "abc<<begriff:142>>";
        assertThrows(RuntimeException.class, () ->
            ReplacementHelper.determinePlaceholderFrontPart(placeholder)
        );
    }

    @Test
    public void determinePlaceholderEmptyFrontPart() {
        String placeholder = "<<:142>>";
        assertThrows(RuntimeException.class, () ->
            ReplacementHelper.determinePlaceholderFrontPart(placeholder)
        );
    }

    @Test
    public void determinePlaceholderBlankFrontPart() {
        String placeholder = "<<   :142>>";
        assertThrows(RuntimeException.class, () ->
            ReplacementHelper.determinePlaceholderFrontPart(placeholder)
        );
    }

    @Test
    public void countPlaceholders() {
        String text = "Der <<obst:1>> und die <<obst:2>> liegen auf dem <<tisch:1>>.";
        String placeholderFrontPart = "obst";
        int actual = ReplacementHelper.countPlaceholders(text, placeholderFrontPart);
        int expected = 2;
        assertEquals(expected, actual);
    }

    @Test
    public void countPlaceholders2() {
        String text = "Der <<obst:1>> und die <<obst:2>> liegen auf dem <<tisch:1>>.";
        String placeholderFrontPart = "tisch";
        int actual = ReplacementHelper.countPlaceholders(text, placeholderFrontPart);
        int expected = 1;
        assertEquals(expected, actual);
    }

    @Test
    public void countPlaceholdersNotFount() {
        String text = "Der <<obst:1>> und die <<obst:2>> liegen auf dem <<tisch:1>>.";
        String placeholderFrontPart = "auto";
        int actual = ReplacementHelper.countPlaceholders(text, placeholderFrontPart);
        int expected = 0;
        assertEquals(expected, actual);
    }

    @Test
    public void getPositionsOfPlaceholders() {
        //List<String> obststuecke = CollectionsHelper.buildListFrom("Apfel", "Birne");
        //List<String> tische = CollectionsHelper.buildListFrom("Küchentisch");
        String ent = "Der <<obst:1>> und die <<obst:2>> liegen auf dem <<tisch:1>>.";

        String obstRegex = "<<obst:(\\d+)>>";
        Pattern obstPattern = Pattern.compile(obstRegex);
        List<Integer> obstPositions = ReplacementHelper.getPositionsOfPlaceholders(ent, obstPattern);
        assertEquals(obstPositions.size(), 2);
        assertEquals(Integer.valueOf(1), obstPositions.get(0));
        assertEquals(Integer.valueOf(2), obstPositions.get(1));

        String tischRegex = "<<tisch:(\\d+)>>";
        Pattern tischPattern = Pattern.compile(tischRegex);
        List<Integer> tischPositions = ReplacementHelper.getPositionsOfPlaceholders(ent, tischPattern);
        assertEquals(tischPositions.size(), 1);
        assertEquals(Integer.valueOf(1), tischPositions.get(0));
    }

}
