#include <print>
#include <fstream>
#include <set>
#include <string>
#include <cctype>
#include <algorithm>
#include <ranges>

// Name der zu untersuchenden Textdatei
const std::string FILENAME("../../04_Data/cont3.txt");

// Lambda-Funktion zum Umwandeln in Kleinschreibung
auto LowerCase = [](char& letter)
{
    letter = std::tolower(letter);
};
// Lambda-Funktion zum Pruefen auf Anfangsbuchstaben
auto OnlyD = [check='d'](std::string_view word)
{
    return word[0] == check;
};

int main()
{
    // Zu untersuchende Datei öffnen
    std::ifstream infile(FILENAME);
    if (!infile)
    {
        std::println("Fehler beim Oeffnen der Datei {}", FILENAME);
        exit(1);
    }

    // Set für Woerter aus Datei anlegen
    std::set<std::string> dictionary;

    // Komplette Datei einlesen und Woerter ablegen
    do
    {
        // Wort aus Datei einlesen
        std::string word;
        infile >> word;
        if (infile.eof())
            continue;
        // Alles in Kleinbuchstaben wandeln
        std::ranges::for_each(word, LowerCase);
        // Interpunktion am Wortende entfernen
        if (auto pos = word.find_first_of(".,!?"); pos != std::string::npos)
            word.erase(word.end() - 1);
        // Im Set ablegen falls Wort nicht schon vorhanden
        auto [pos, success] = dictionary.insert(word);
    } while (!infile.eof());

    // Alle Woerter aus Datei ausgeben
    // Alternativ waere auch for_each() moeglich
    std::println("In der Datei enthaltene Worte:");
    int index = 0;
    for (const auto& word : dictionary)
    {
        std::print("{}, ", word);
        if (++index % 8 == 0)
            std::println("");
    }

    // Nun alle Woerter mit einem bestimmten Buchstaben ausgeben
    // Es werden nur die Woerter ausgegeben, fuer der Filter-View
    // true zurueck gibt.
    std::println("\n\nAlle Woerter mit dem Buchstaben 'd':");
    std::ranges::for_each(dictionary | std::views::filter(OnlyD),
        [](std::string_view word) { std::print("{},", word); });
    std::println("\nAnzahl der Woerter (ohne Duplikate): {}", dictionary.size());
}
