package UE06_151024_RegExp2;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UE06_Main {
    public static void main(String[] args) {
        Path htmlDatei = Path.of("src/UE06_151024_RegExp2/index.html");
        Path cssDatei = Path.of("src/UE06_151024_RegExp2/styles.css");
        System.out.println(tagStatistik(htmlDatei));
        System.out.println(links(htmlDatei));
        System.out.println(domains(htmlDatei));
        System.out.println(klassen(cssDatei));
        System.out.println(removeMultipleSpaces("Hallo   Du             kek   !"));
        System.out.println(bigStartingLetter("Hallo   du kek   !"));
        System.out.println(lineSplitting("Es war einmal ein Lehrer namens Herr Klein, der in einem kleinen Dorf am Rande eines großen, dichten Waldes lebte. Aber Herr Klein war kein gewöhnlicher Lehrer. Während die meisten Lehrer Lesen, Schreiben und Rechnen unterrichteten, hatte Herr Klein eine ganz besondere Leidenschaft: das Programmieren. Seine Augen leuchteten jedes Mal auf, wenn er über Code sprach, und er konnte Stunden damit verbringen, knifflige Probleme zu lösen.\n" + "\n" + "Herr Klein war bekannt für seine Geduld und sein freundliches Wesen. Die Dorfbewohner liebten ihn, denn er brachte den Kindern bei, wie man Programme schreibt, die die Welt verbessern konnten. Die Kinder nannten ihn liebevoll \"den Magier des Codes\", denn er zauberte scheinbar mit Zahlen und Buchstaben, um unglaubliche Dinge zu erschaffen.\n" + "\n" + "Eines Tages hörte Herr Klein von einer alten Legende, die in seinem Dorf seit Generationen erzählt wurde. Tief im Herzen des Waldes sollte es einen magischen Code geben, den niemand je vollständig entschlüsselt hatte. Dieser Code, so hieß es, hatte die Macht, jede Frage der Welt zu beantworten, jedes Problem zu lösen und jede Vision wahr werden zu lassen. Doch er war verschlüsselt und versteckt in einer uralten Höhle, die nur denjenigen zugänglich war, die das Herz eines wahren Programmierers hatten.\n" + "\n" + "Fasziniert von dieser Legende beschloss Herr Klein, sich auf die Suche nach dem magischen Code zu machen. Er packte seinen Laptop, sein Lieblingsbuch über Algorithmen und machte sich auf den Weg in den dichten Wald. Der Weg war lang und voller Herausforderungen. Rätselhafte Pfade, die sich ständig veränderten, zwangen Herrn Klein dazu, seinen Verstand zu nutzen und clevere Algorithmen zu entwickeln, um die richtige Richtung zu finden. Manchmal musste er Code schreiben, um Brücken über tiefe Schluchten zu bauen oder wilde Tiere zu beruhigen, indem er für sie kleine Spiele programmierte.\n" + "\n" + "Nach vielen Tagen erreichte er endlich die alte Höhle. Ihre Wände waren mit uralten Runen bedeckt, die wie Programmzeilen wirkten. Herr Klein erkannte sofort, dass dies der magische Code war. Doch es war ein Rätsel, so komplex, dass es Jahrhunderte dauern würde, es von Hand zu lösen. Aber Herr Klein war nicht entmutigt. Er setzte sich hin, öffnete seinen Laptop und begann, den Code zu analysieren.\n" + "\n" + "Stunden wurden zu Tagen, und Tage wurden zu Wochen. Aber Herr Klein gab nicht auf. Schließlich, nach einem letzten tiefen Atemzug, schrieb er die letzte Zeile Code, die den magischen Code entsperrte. Mit einem leisen Klicken öffnete sich die Höhle, und eine leuchtende Kugel schwebte in die Luft. Aus ihr heraus hörte Herr Klein eine sanfte, weise Stimme:\n" + "\n" + "\"Du hast bewiesen, dass du das Herz eines wahren Programmierers trägst. Der magische Code gehört nun dir. Nutze ihn weise, um Gutes in die Welt zu bringen.\"\n" + "\n" + "Doch Herr Klein, so sehr er auch von der Macht des Codes beeindruckt war, wusste, dass die wahre Magie nicht darin lag, alle Antworten zu kennen. Es war die Freude am Lernen, am Lösen von Problemen und am Teilen seines Wissens mit anderen. Also kehrte er ins Dorf zurück und lehrte weiterhin seine Schüler. Aber jetzt brachte er ihnen nicht nur das Programmieren bei – er zeigte ihnen auch, wie man mit Geduld, Kreativität und einer Portion Mut selbst die kniffligsten Herausforderungen meistert.\n" + "\n" + "Und so lebte Herr Klein glücklich und zufrieden. Er fand Freude darin, seine Schüler zu inspirieren, und der magische Code ruhte sicher in seinem Herzen, bereit, nur dann genutzt zu werden, wenn es wirklich notwendig war. Und wenn die Dorfbewohner an seinen Fenstern vorbeigingen, konnten sie oft das leise Klicken seiner Tastatur hören, während Herr Klein weiter seine Leidenschaft verfolgte, eine Zeile Code nach der anderen.\n" + "\n" + "Und wenn er nicht gestorben ist, dann programmiert er noch heute."));
        System.out.println(lineSplitting("hgkjhgsdhjgsjhfgshjfghjsgfhjgshjkghgfjhsghjfgsjhkgfjksgfhjgdhgdfjhgsdhjgfdhjsgdfhjdfghjksgjhsdghjsdfgdshjgfjhsdgfjhs sdhjfgsdhfsdjhkshfdsghjdghjsghjdfgjhsgfsgfhjsgdhjfgsjfgjhsgdfshjgfshjdgfhjsdgjhsgfjhsgdjfgsjhgfdhjsgjhgdfjsdfg jfhgshjsdfgjsdgfgsfghd dsgsdfj"));
    }

    public static Map<String, Double> tagStatistik(Path htmlDatei) {
        Map<String, Double> statistik = new TreeMap<>();
        int counter = 0;
        try {
            for (String line : Files.readAllLines(htmlDatei)) {
                Matcher matcher = Pattern.compile("(?<=<)\\w+").matcher(line);
                while (matcher.find()) {
                    statistik.put(matcher.group(), statistik.getOrDefault(matcher.group(), 0.0) + 1);
                    counter++;
                }
            }
        } catch (IOException e) {
            System.err.println("Error while reading/ analysing File!");
        }
        for (Map.Entry<String, Double> entry : statistik.entrySet())
            statistik.put(entry.getKey(), entry.getValue() / counter);
        return statistik;
    }

    public static Set<String> links(Path htmlDatei) {
        Set<String> links = new HashSet<>();
        try {
            for (String line : Files.readAllLines(htmlDatei)) {
                Matcher matcher = Pattern.compile("(?<=href=\")https?://[^\"]+").matcher(line);
                while (matcher.find()) links.add(matcher.group());
            }
        } catch (IOException e) {
            System.err.println("Error while reading/ analysing File!");
        }
        return links;
    }

    public static Set<String> domains(Path htmlDatei) {
        Set<String> domains = new HashSet<>();
        try {
            Pattern pattern = Pattern.compile("(?<=href=\"https?://)(?:\\w+\\.)*([\\w-]+\\.[a-zA-Z]{2,})");
            for (String line : Files.readAllLines(htmlDatei)) {
                Matcher matcher = pattern.matcher(line);
                while (matcher.find()) domains.add(matcher.group(1));
            }
        } catch (IOException e) {
            System.err.println("Error while reading/ analysing File!");
        }
        return domains;
    }

    public static Set<String> klassen(Path cssDatei) {
        Set<String> classes = new HashSet<>();
        try {
            Pattern pattern = Pattern.compile("(?<=\\.)[a-zA-Z]+[\\w-]*(?=.*\\{)");
            for (String line : Files.readAllLines(cssDatei)) {
                Matcher matcher = pattern.matcher(line);
                while (matcher.find()) classes.add(matcher.group());
            }
        } catch (IOException e) {
            System.err.println("Error while reading/ analysing File!");
        }
        return classes;
    }

    public static String removeMultipleSpaces(String string) {
        return string.replaceAll(" +", " ");
    }

    public static String bigStartingLetter(String string) {
        return Pattern.compile("\\b[a-z]").matcher(string).replaceAll(matchResult -> matchResult.group().toUpperCase());
    }

    public static String lineSplitting(String string) {
        if (Pattern.compile("\\b\\w{41,}\\b").matcher(string).find())
            throw new RuntimeException("A word with more than 40 letters was found!");
        Matcher matcher = Pattern.compile(".{1,40}(?:\\s|$)").matcher(string.replaceAll("\n", " "));
        StringBuilder output = new StringBuilder();
        while (matcher.find()) output.append(matcher.group().trim()).append("\n");
        return output.toString();
    }
}