package org.jabref.logic.integrity;

import java.util.Optional;

import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.database.BibDatabaseMode;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class EditionCheckerTest {
    @Test
    void isFirstCharacterANumber() {
        assertTrue(createSimpleEditionChecker(new BibDatabaseContext(), false).isFirstCharDigit("0HelloWorld"));
    }

    @Test
    void isFirstCharacterANumberFalseForEmptyString() {
        assertFalse(createSimpleEditionChecker(new BibDatabaseContext(), false).isFirstCharDigit(""));
    }

    @Test
    void isFirstCharacterNotANumber() {
        assertFalse(createSimpleEditionChecker(new BibDatabaseContext(), false).isFirstCharDigit("HelloWorld"));
    }

    @Test
    void editionCheckerDoesNotComplainIfAllowIntegerEditionIsEnabled() {
        assertEquals(Optional.empty(), createSimpleEditionChecker(new BibDatabaseContext(), true).checkValue("2"));
    }

    @Test
    void bibTexAcceptsOrdinalNumberInWordsWithCapitalFirstLetter() {
        assertEquals(Optional.empty(), createBibtexEditionChecker(true).checkValue("Second"));
    }

    @Test
    void bibTexDoesNotAcceptOrdinalNumberInWordsWithNonCapitalFirstLetter() {
        assertNotEquals(Optional.empty(), createBibtexEditionChecker(true).checkValue("second"));
    }

    @Test
    void bibTexAcceptsIntegerInputInEdition() {
        assertEquals(Optional.empty(), createBibtexEditionChecker(true).checkValue("2"));
    }

    @Test
    void bibTexAcceptsOrdinalNumberInNumbers() {
        assertEquals(Optional.empty(), createBibtexEditionChecker(true).checkValue("2nd"));
    }

    @Test
    void bibTexEmptyValueAsInput() {
        assertEquals(Optional.empty(), checker.checkValue(""));
    }

    @Test
    void bibTexNullValueAsInput() {
        assertEquals(Optional.empty(), checker.checkValue(null));
    }

    @Test
    void bibTexDoesNotAcceptIntegerOnly() {
        var editionChecker = new EditionChecker(bibtex, false);
        assertEquals(Optional.of(Localization.lang("no integer as values for edition allowed")), editionChecker.checkValue("3"));
    }

    @Test
    void bibTexAcceptsFirstEditionAlsoIfIntegerEditionDisallowed() {
        var editionChecker = new EditionChecker(bibtex, false);
        assertEquals(Optional.of(Localization.lang("edition of book reported as just 1")), editionChecker.checkValue("1"));
    }

    @Test
    void bibLaTexAcceptsEditionWithCapitalFirstLetter() {
        assertEquals(Optional.empty(), createBiblatexEditionChecker(true).checkValue("Edition 2000"));
    }

    @Test
    void bibLaTexAcceptsIntegerInputInEdition() {
        assertEquals(Optional.empty(), createBiblatexEditionChecker(true).checkValue("2"));
    }

    @Test
    void bibLaTexAcceptsEditionAsLiteralString() {
        assertEquals(Optional.empty(), createBiblatexEditionChecker(true).checkValue("Third, revised and expanded edition"));
    }

    @Test
    void bibLaTexDoesNotAcceptOrdinalNumberInNumbers() {
        assertNotEquals(Optional.empty(), createBiblatexEditionChecker(true).checkValue("2nd"));
    }

    private EditionChecker createBibtexEditionChecker(Boolean allowIntegerEdition) {
        BibDatabaseContext bibtex = new BibDatabaseContext();
        bibtex.setMode(BibDatabaseMode.BIBTEX);
        return new EditionChecker(bibtex, allowIntegerEdition);
    }

    private EditionChecker createBiblatexEditionChecker(Boolean allowIntegerEdition) {
        BibDatabaseContext biblatex = new BibDatabaseContext();
        biblatex.setMode(BibDatabaseMode.BIBLATEX);
        return new EditionChecker(biblatex, allowIntegerEdition);
    }

    private EditionChecker createSimpleEditionChecker(BibDatabaseContext bibDatabaseContextEdition, boolean allowIntegerEdition) {
        return new EditionChecker(bibDatabaseContextEdition, allowIntegerEdition);
    }
}

@@ -2005,38 +2005,64 @@
 ional.empty(), c
-hecker
+reateBibtexEditionChecker(false)
 .checkValue(%22%22))
@@ -2156,22 +2156,48 @@
 pty(), c
-hecker
+reateBibtexEditionChecker(false)
 .checkVa
@@ -2273,72 +2273,8 @@
 ) %7B%0A
-        var editionChecker = new EditionChecker(bibtex, false);%0A
     
@@ -2362,25 +2362,37 @@
 allowed%22)), 
-e
+createBibtexE
 ditionChecke
@@ -2384,32 +2384,39 @@
 exEditionChecker
+(false)
 .checkValue(%223%22)
@@ -2508,72 +2508,8 @@
 ) %7B%0A
-        var editionChecker = new EditionChecker(bibtex, false);%0A
     
@@ -2595,17 +2595,29 @@
 t 1%22)), 
-e
+createBibtexE
 ditionCh
@@ -2621,16 +2621,23 @@
 nChecker
+(false)
 .checkVa

Fix tests