package de.dergrafiker.filenamecleaner;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.nio.file.FileVisitResult.CONTINUE;

public class PrintFiles extends SimpleFileVisitor<Path> {
    private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
    private static final Set<Character> IGNORED = fill();

    private static Set<Character> fill() {
        Set<Character> ignored = new HashSet<>();
        Collections.addAll(ignored, '[', ']', '(', ')', ',', ';', ' ', '.', '&', '+', '#', '$', '!', '\'');
        return ignored;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
        final File file = dir.toFile();
        String oldName = file.getName();
        if (FilenameChecker.isInvalid(oldName, file.isDirectory())) {
            String cleaned = FilenameCleaner.clean(oldName, file.isDirectory());

            Set<Character> removedChars = getRemovedChars(oldName, cleaned);

            if (removedChars.size() > 0) {
                LOGGER.info("{} has removed >> {} << {}",
                            oldName,
                            StringUtils.join(removedChars),
                            cleaned);
            }

//            LOGGER.info("'{}' => '{}' [{}]",
//                        StringUtils.rightPad(oldName, 70, ' '),
//                        StringUtils.rightPad(cleaned, 70, ' '),
//                        file.getParentFile().getAbsolutePath());
        }
//        LOGGER.info("walked dir {}", dir);
        return CONTINUE;
    }

    private Set<Character> getRemovedChars(String oldName, String cleaned) {
        Set<Character> removedChars = getUniqueLowerCaseChars(oldName);
        removedChars.removeAll(getUniqueLowerCaseChars(cleaned));
        removedChars.removeAll(IGNORED);
        return removedChars;
    }

    private Set<Character> getUniqueLowerCaseChars(String oldName) {
        Stream<Character> characterStream = oldName.chars()
                .mapToObj(c -> (char) Character.toLowerCase(c));

        return characterStream.collect(Collectors.toSet());
    }
}

@@ -1007,17 +1007,97 @@
 on exc) 
-%7B
+throws IOException %7B%0A        if (exc != null) %7B%0A            throw exc;%0A        %7D%0A
 %0A       
@@ -1472,16 +1472,29 @@
 R.info(%22
+REMOVEDCHARS 
 %7B%7D has r
@@ -1664,18 +1664,16 @@
      %7D%0A%0A
-//
         
@@ -1689,16 +1689,23 @@
 R.info(%22
+RENAME 
 '%7B%7D' =%3E 
@@ -1716,18 +1716,16 @@
  %5B%7B%7D%5D%22,%0A
-//
         
@@ -1744,116 +1744,50 @@
     
-StringUtils.rightPad(oldName, 70, ' '),%0A//                        StringUtils.rightPad(cleaned, 70, ' '),%0A//
+oldName,%0A                        cleaned,%0A
     
@@ -1861,10 +1861,8 @@
   %7D%0A
-//
     
@@ -1882,14 +1882,14 @@
 fo(%22
-walked
+WALKED
  dir

throw exceptions; reactivate logging