#!/usr/bin/env python3

import re
import sys
import fileinput
from collections import Counter

if len(sys.argv) < 2:
    sys.exit(f'Verwendung: {sys.argv[0]} lyrikdatei')

transtable1 = str.maketrans('Jjſ', 'Iis')
transtable2 = str.maketrans('âêîôûëÂÊÎÔÛËJjſcCvV', 'aeioueAEIOUIEiskKfF')

wortliste  = set()  # Liste der Wörter
wortliste2 = set()  # Liste der Wörter ohne Akzente
wortliste3 = set()  # Liste der Wörter ohne Flexionsendungen

anz_unklare_faelle = 0

def normalisiere(wort):
    wort = wort.replace('æ', 'ae').replace('œ', 'oe')
    wort = wort.replace('ͤ', 'e').replace('ͮ', 'v').replace('ͦ', 'o')
    return wort

def flektion_entfernen(wort):
    if (match := re.match(r'(...+)(e([mnrst]|st|nt)?|iu)$', wort)):
        wort = match.group(1)
    elif (match := re.match(r'(...+)e([ns])?$', wort)):
        wort = match.group(1)
    elif (match := re.match(r'(...+[r])[s]$', wort)):
        wort = match.group(1)
    return wort

def zur_wortliste_hinzufügen(wort):
    norm_wort = normalisiere(wort)
    wortliste.add(norm_wort)
    
    # Schreibung ohne Akzente und ohne j und langes s
    norm_wort2 = norm_wort.translate(transtable2)
    wortliste2.add(norm_wort2)
        
    # Flexionsendungen abtrennen
    wortliste3.add(norm_wort2)
    norm_wort2 = flektion_entfernen(norm_wort2)
    wortliste3.add(norm_wort2)
    
        
def kleinschreibung(wort):
    global anz_unklare_faelle
    
    norm_wort = normalisiere(wort)
    
    # Taucht das Wort nur kleingeschrieben in der Wortliste auf?
    if norm_wort.lower() in wortliste and norm_wort not in wortliste:
        return wort.lower()
    # Taucht das Wort nur großgeschrieben in der Wortliste auf?
    if norm_wort in wortliste and norm_wort.lower() not in wortliste:
        return wort
    
    # Taucht das Wort mit i statt i oder mit s statt ſ in der Wortliste auf?
    norm_wort2 = norm_wort.translate(transtable1)
    if norm_wort2.lower() in wortliste and norm_wort2 not in wortliste:
        return wort.lower()
    if norm_wort2 in wortliste and norm_wort2.lower() not in wortliste:
        return wort
    
    # Taucht das Wort ohne Akzente in der Wortliste ohne Akzente auf?
    norm_wort2 = norm_wort2.translate(transtable2)
    if norm_wort2.lower() in wortliste2 and norm_wort2 not in wortliste2:
        return wort.lower()
    if norm_wort2 in wortliste2 and norm_wort2.lower() not in wortliste2:
        return wort
    
    # Taucht das Wort ohne Flexionsendung in der Wortliste ohne Flexionsendungen auf?
    norm_wort2 = flektion_entfernen(norm_wort2)
    if norm_wort2.lower() in wortliste3 and norm_wort2 not in wortliste3:
        return wort.lower()
    if norm_wort2 in wortliste3 and norm_wort2.lower() not in wortliste3:
        return wort

    # Ist die Kleingeschreibung deutlich häufiger als die Großschreibung?
    if wortfreq[wort.lower()] > wortfreq[wort] * 1.5 + 1:
        return wort.lower()
    
    # Ist die Großschreibung deutlich häufiger als die Kleingeschreibung?
    if wortfreq[wort.lower()] < wortfreq[wort] * 0.7 - 1:
        return wort
    
    # Markierung des Wortes zur manuellen Korrektur
    anz_unklare_faelle += 1
    return '<unklar>' + wort


# Wortliste einlesen
with open("lib/lemmaliste.txt") as file:
    for zeile in file:
        # Kommentare entfernen
        wort = re.sub(r'\s*#.*', '', zeile.strip())
        if wort:
            zur_wortliste_hinzufügen(wort)

# Eingabe einlesen
zeilen = [zeile.strip() for zeile in fileinput.input()]

# Worthäufigkeiten berechnen
wortfreq = Counter(re.findall(r'\w+', ' '.join(zeilen)))

# Schreibung normalisieren
for zeile in zeilen:
    # großgeschriebenes Wort am Zeilenanfang suchen
    match = re.match(r'((?:.*[.:!?])?\W*)([A-ZÄÖÜÂÊÎÔÛ]\w*)(.*)', zeile)
    if match:
        initial, wort, rest = match.groups()
        zeile = initial + kleinschreibung(wort) + rest
    print(zeile)

if anz_unklare_faelle > 0 :
    print('\nBitte korrigieren Sie noch die mit "<unklar>" markierten '
          'Textstellen in der Ausgabe von Hand.', file=sys.stderr)
