package be.crydust.tokenreplacer;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Callable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author kristof
 */
public class FilesFinder implements Callable<List<Path>> {

    private static final Logger LOGGER = LoggerFactory.getLogger(FilesFinder.class);

    private final Path path;
    private final PathMatcher includesMatcher;
    private final PathMatcher excludesMatcher;

    private static final PathMatcher ALL_FALSE = it -> false;

    /**
     * FilesFinder with only one include pattern
     *
     * @param path
     * @param include
     * @param excludes
     */
    public FilesFinder(Path path, String include, String[] excludes) {
        this(path, new String[]{include}, excludes);
    }

    /**
     * FilesFinder with only one multiple include patterns
     *
     * @param path
     * @param includes
     * @param excludes
     */
    public FilesFinder(Path path, String[] includes, String[] excludes) {
        Objects.requireNonNull(path);
        Objects.requireNonNull(includes);
        Objects.requireNonNull(excludes);
        if (includes.length == 0) {
            throw new IllegalArgumentException("includes should not be empty");
        }
        this.path = path;
        this.includesMatcher = FileSystems.getDefault()
                .getPathMatcher(patternsToGlob(includes));
        if (excludes.length == 0) {
            this.excludesMatcher = ALL_FALSE;
        } else {
            this.excludesMatcher = FileSystems.getDefault()
                    .getPathMatcher(patternsToGlob(excludes));
        }
    }

    @Override
    public List<Path> call() {
        final List<Path> files = new ArrayList<>();
        try {
            Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                    Path relativePath = path.relativize(file);
                    if (includesMatcher.matches(relativePath)
                            && !excludesMatcher.matches(relativePath)) {
                        files.add(file);
                    }
                    return FileVisitResult.CONTINUE;
                }
            });
        } catch (IOException ex) {
            System.err.println(ex.getMessage());
            LOGGER.error(null, ex);
        }
        return files;
    }

    private static String escapeGlob(String pattern) {
        return pattern.replaceAll("([\\[\\]!{}])", "\\\\$1");
    }

    private static String patternsToGlob(String[] patterns) {
        StringBuilder sb = new StringBuilder();
        int partCount = 0;
        for (String pattern : patterns) {
            Strings.requireNonEmpty(pattern);
            if (pattern.startsWith("**/")) {
                String extraPattern = pattern.substring(3);
                Strings.requireNonEmpty(extraPattern);
                partCount++;
                sb.append(escapeGlob(extraPattern)).append(',');
            }
            partCount++;
            sb.append(escapeGlob(pattern)).append(',');
        }
        sb.setLength(sb.length() - 1);
        if (partCount > 1) {
            sb.insert(0, '{').append('}');
        }
        sb.insert(0, "glob:");
        return sb.toString();
    }

}

@@ -39,28 +39,51 @@
 ort 
-java.io.IOException;
+static java.util.stream.Collectors.toList;%0A
 %0Aimp
@@ -95,28 +95,22 @@
 ava.
-n
 io.
-file.FileSystems
+IOException
 ;%0Aim
@@ -132,27 +132,23 @@
 ile.File
-VisitResult
+Systems
 ;%0Aimport
@@ -246,114 +246,24 @@
 ava.
-nio.file.SimpleFileVisitor;%0Aimport java.nio.file.attribute.BasicFileAttributes;%0Aimport java.util.ArrayList
+util.Collections
 ;%0Aim
@@ -1942,247 +1942,85 @@
     
-final List%3CPath%3E files = new ArrayList%3C%3E();%0A        try %7B%0A            Files.walkFileTree(path, new SimpleFileVisitor%3CPath%3E() %7B%0A                @Override%0A                public FileVisitResult visitFile(Path file, BasicFileAttributes
+try %7B%0A            return Files.find(path, Integer.MAX_VALUE, (file,
  attrs)
+ -%3E
  %7B%0A 
@@ -2034,20 +2034,16 @@
         
-    
 Path rel
@@ -2089,32 +2089,31 @@
             
-    if (
+return 
 includesMatc
@@ -2138,20 +2138,16 @@
 vePath)%0A
-    
         
@@ -2207,159 +2207,41 @@
 ath)
-) %7B%0A                        files.add(file);%0A                    %7D%0A                    return FileVisitResult.CONTINUE;%0A                %7D%0A            %7D
+;%0A            %7D).collect(toList()
 );%0A 
@@ -2388,13 +2388,31 @@
 urn 
-files
+Collections.emptyList()
 ;%0A  

Simplify FilesFinder