package UE17_130325_Streams4;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class UE17_Streams4 {
    static Map<Character, String> letterMorseMap = Map.ofEntries(Map.entry('a', ".-"), Map.entry('b', "-..."), Map.entry('c', "-.-."), Map.entry('d', "-.."), Map.entry('e', "."), Map.entry('f', "..-."), Map.entry('g', "--."), Map.entry('h', "...."), Map.entry('i', ".."), Map.entry('j', ".---"), Map.entry('k', "-.-"), Map.entry('l', ".-.."), Map.entry('m', "--"), Map.entry('n', "-."), Map.entry('o', "---"), Map.entry('p', ".--."), Map.entry('q', "--.-"), Map.entry('r', ".-."), Map.entry('s', "..."), Map.entry('t', "-"), Map.entry('u', "..-"), Map.entry('v', "...-"), Map.entry('w', ".--"), Map.entry('x', "-..-"), Map.entry('y', "-.--"), Map.entry('z', "--.."), Map.entry('0', "-----"), Map.entry('1', ".----"), Map.entry('2', "..---"), Map.entry('3', "...--"), Map.entry('4', "....-"), Map.entry('5', "....."), Map.entry('6', "-...."), Map.entry('7', "--..."), Map.entry('8', "---.."), Map.entry('9', "----."), Map.entry('ä', ".-.-"), Map.entry('ü', "..--"), Map.entry('ö', "---."));
    static Map<String, Character> morseLetterMap = letterMorseMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));

    public static void main(String[] args) {
        AtomicInteger counter = new AtomicInteger();
        Path path = Path.of("C:/Users/alex/Downloads");
        biggestFilesA(path, 30).forEach(p -> System.out.println(counter.getAndIncrement() + ": " + p + " - " + p.toFile().length() + " Bytes"));
        counter.set(0);
        System.out.println("\n");
        biggestFilesB(path, 30).forEach(p -> System.out.println(counter.getAndIncrement() + ": " + p + " - " + p.toFile().length() + " Bytes"));
        counter.set(0);
        System.out.println("\n");
        olderThan(path, Path.of("C:/Users/alex/Downloads/XG_T.docx")).forEach(p -> {
            try {
                System.out.println(counter.getAndIncrement() + ": " + p + " - " + Files.readAttributes(p, BasicFileAttributes.class).creationTime());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
        counter.set(0);
        System.out.println("\n");
        olderThan(path, Path.of("C:/Users/alex/Downloads/new")).forEach(p -> {
            try {
                System.out.println(counter.getAndIncrement() + ": " + p + " - " + Files.readAttributes(p, BasicFileAttributes.class).creationTime());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
        System.out.println(toMorseCode("Älle lieben Java!"));
        System.out.println(morseToText(toMorseCode("Älle lieben Java!")));
        System.out.println(morseToText(toMorseCode("Älle lieben Java! Älle lieben Java2")));
    }

    public static List<Path> biggestFilesA(Path dir, int n) {
        try (Stream<Path> content = Files.walk(dir, 1)) {
            return content.filter(Files::isRegularFile).sorted((x, y) -> Long.compare(y.toFile().length(), x.toFile().length())).limit(n).toList();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static List<Path> biggestFilesB(Path dir, int n) {
        try (Stream<Path> content = Files.walk(dir)) {
            return content.filter(Files::isRegularFile).sorted((x, y) -> Long.compare(y.toFile().length(), x.toFile().length())).limit(n).toList();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static List<Path> olderThan(Path dir, Path reference) {
        try (Stream<Path> content = Files.list(dir)) {
            FileTime referenceTime = Files.readAttributes(reference, BasicFileAttributes.class).creationTime();
            return content.filter(path -> {
                try {
                    FileTime pathTime = Files.readAttributes(path, BasicFileAttributes.class).creationTime();
                    if (Files.isDirectory(reference) && Files.isDirectory(path)) {
                        return referenceTime.compareTo(pathTime) > 0;
                    } else if (Files.isRegularFile(reference) && Files.isRegularFile(path)) {
                        return referenceTime.compareTo(pathTime) > 0;
                    }
                } catch (IOException e) {
                    return false;
                }
                return false;
            }).toList();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static String toMorseCode(String text) {
        return text.toLowerCase().chars().mapToObj(c -> {
            if (c == ' ') return "/";
            if (String.valueOf((char) c).matches("[!.?\n]")) return "///";
            return "/" + letterMorseMap.getOrDefault((char) c, "");
        }).collect(Collectors.joining());
    }


    public static String morseToText(String morse) {
        return Arrays.stream(morse.split("///")).map(sentence -> Arrays.stream(sentence.split("//")).map(word -> Arrays.stream(word.split("/")).map(letter -> String.valueOf(morseLetterMap.getOrDefault(letter, ' '))).collect(Collectors.joining())).collect(Collectors.joining(" ")).trim()).collect(Collectors.joining(". ")).trim();
    }
}
