package de.gecheckt.pdf.umbenenner.application.service;

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

import org.junit.jupiter.api.Test;

/**
 * Unit tests for {@link TitleCharacterRule}.
 * <p>
 * Prüft die kanonische Zeichenerlaubnis-Regel: Buchstaben (einschließlich deutscher Umlaute
 * und ß), Ziffern, ASCII-Leerzeichen, Bindestriche, Punkte, Kommas und Ampersands sind
 * erlaubt; alles andere ist nicht erlaubt.
 */
class TitleCharacterRuleTest {

    // -------------------------------------------------------------------------
    // Allowed characters
    // -------------------------------------------------------------------------

    @Test
    void isAllowed_lettersOnly_returnsTrue() {
        assertThat(TitleCharacterRule.isAllowed("Stromabrechnung")).isTrue();
    }

    @Test
    void isAllowed_lettersAndDigits_returnsTrue() {
        assertThat(TitleCharacterRule.isAllowed("Rechnung 2026")).isTrue();
    }

    @Test
    void isAllowed_germanUmlauts_returnsTrue() {
        assertThat(TitleCharacterRule.isAllowed("Müller Überprüfung")).isTrue();
    }

    @Test
    void isAllowed_germanSzlig_returnsTrue() {
        assertThat(TitleCharacterRule.isAllowed("Straße")).isTrue();
    }

    @Test
    void isAllowed_hyphen_returnsTrue() {
        assertThat(TitleCharacterRule.isAllowed("Strom-Rechnung")).isTrue();
    }

    @Test
    void isAllowed_hyphenWithSpaces_returnsTrue() {
        assertThat(TitleCharacterRule.isAllowed("Kfz-Haftpflicht 2026")).isTrue();
    }

    @Test
    void isAllowed_comma_returnsTrue() {
        assertThat(TitleCharacterRule.isAllowed("Müller, Hans")).isTrue();
    }

    @Test
    void isAllowed_ampersand_returnsTrue() {
        assertThat(TitleCharacterRule.isAllowed("Müller & Söhne")).isTrue();
    }

    @Test
    void isAllowed_dotCommaAmpersand_returnsTrue() {
        assertThat(TitleCharacterRule.isAllowed("Firma Dr. Meyer, Müller & Co.")).isTrue();
    }

    @Test
    void isAllowed_emptyString_returnsTrue() {
        assertThat(TitleCharacterRule.isAllowed("")).isTrue();
    }

    // -------------------------------------------------------------------------
    // Disallowed characters
    // -------------------------------------------------------------------------

    @Test
    void isAllowed_exclamationMark_returnsFalse() {
        assertThat(TitleCharacterRule.isAllowed("Rechnung!")).isFalse();
    }

    @Test
    void isAllowed_dot_returnsTrue() {
        assertThat(TitleCharacterRule.isAllowed("Rechnung.Kopie")).isTrue();
    }

    @Test
    void isAllowed_colon_returnsFalse() {
        assertThat(TitleCharacterRule.isAllowed("Betreff: Rechnung")).isFalse();
    }

    @Test
    void isAllowed_slash_returnsFalse() {
        assertThat(TitleCharacterRule.isAllowed("Rg/Strom")).isFalse();
    }

    @Test
    void isAllowed_backslash_returnsFalse() {
        assertThat(TitleCharacterRule.isAllowed("Rg\\Strom")).isFalse();
    }

    @Test
    void isAllowed_questionMark_returnsFalse() {
        assertThat(TitleCharacterRule.isAllowed("Was?")).isFalse();
    }

    @Test
    void isAllowed_asterisk_returnsFalse() {
        assertThat(TitleCharacterRule.isAllowed("Rech*nung")).isFalse();
    }

    @Test
    void isAllowed_atSign_returnsFalse() {
        assertThat(TitleCharacterRule.isAllowed("user@mail")).isFalse();
    }

    @Test
    void isAllowed_parenthesis_returnsFalse() {
        assertThat(TitleCharacterRule.isAllowed("Rechnung (2026)")).isFalse();
    }

    @Test
    void isAllowed_underscore_returnsFalse() {
        assertThat(TitleCharacterRule.isAllowed("Rechnung_2026")).isFalse();
    }

    // Windows-Sonderzeichen müssen weiterhin abgelehnt werden
    @Test
    void isAllowed_doubleQuote_returnsFalse() {
        assertThat(TitleCharacterRule.isAllowed("Rechnung \"2026\"")).isFalse();
    }

    @Test
    void isAllowed_lessThan_returnsFalse() {
        assertThat(TitleCharacterRule.isAllowed("Rg < 2026")).isFalse();
    }

    @Test
    void isAllowed_greaterThan_returnsFalse() {
        assertThat(TitleCharacterRule.isAllowed("Rg > 2026")).isFalse();
    }

    @Test
    void isAllowed_pipe_returnsFalse() {
        assertThat(TitleCharacterRule.isAllowed("Rg | Strom")).isFalse();
    }
}
