package fr.tikione.steam.cleaner.util;

import fr.tikione.ini.util.StringHelper;
import fr.tikione.steam.cleaner.gui.dialog.JFrameMain;

import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.regex.Pattern;

/**
 * File utilities.
 */
public class FileUtils {
    
    /** Suppresses default constructor, ensuring non-instantiability. */
    private FileUtils() {
    }
    
    /**
     * List all files and folders of a specific folder with a recursive search.
     *
     * @param jframe the frame to show progress.
     * @param files the collection of files and folder to complete with results.
     * @param folders the base paths to initiate research from.
     * @param depth the recursive search depth.
     * @param dangerousFolders list of folders patterns to exclude.
     */
    public static void listDir(JFrame jframe, Collection<File> files, Collection<File> folders, int depth,
                               final List<Pattern> dangerousFolders) {
        String frameTitle = jframe.getTitle();
        try {
            for (File folder : folders) {
                Log.info("Folder to scan: '" + folder.getAbsolutePath() + '\'');
                try {
                    files.addAll(org.apache.commons.io.FileUtils.listFiles(folder, null, false));
                    File[] subFolders;
                    subFolders = folder.listFiles((File pathname) -> {
                        boolean accept;
                        if (pathname.isDirectory()) {
                            accept = true;
                            for (Pattern dangerousPatt : dangerousFolders) {
                                if (StringHelper.checkRegex(pathname.getAbsolutePath(), dangerousPatt)) {
                                    accept = false;
                                    Log.info("Skipped hazardous place: '" + pathname + "'");
                                    break;
                                }
                            }
                        } else {
                            accept = false;
                        }
                        return accept;
                    });
                    if (depth > 0 && subFolders != null) {
                        for (File subFolder : subFolders) {
                            if (JFrameMain.isCLOSING_APP()) {
                                break;
                            }
                            files.add(subFolder);
                            listDirNoRecount(jframe, files, subFolder, depth - 1, dangerousFolders); // FIXME needs optimization (duplicated code: listDirNoRecount)
                        }
                    }
                } catch (Exception ex) {
                    Log.error(ex);
                }
            }
        } finally {
            jframe.setTitle(frameTitle);
        }
    }
    
    /**
     * List all files and folders of a specific folder with a recursive search.
     *
     * @param files the collection of files and folder to complete with results.
     * @param folder the base path to initiate research from.
     * @param depth the recursive search depth.
     * @param dangerousFolders list of folders patterns to exclude.
     */
    private static void listDirNoRecount(final JFrame jframe, Collection<File> files, File folder, int depth,
                                         final List<Pattern> dangerousFolders) {
        jframe.setTitle(folder.getAbsolutePath() + File.separatorChar);
        files.addAll(org.apache.commons.io.FileUtils.listFiles(folder, null, false));
        File[] subFolders = folder.listFiles((File pathname) -> {
            boolean accept;
            if (pathname.isDirectory()) {
                accept = true;
                for (Pattern dangerousPatt : dangerousFolders) {
                    if (StringHelper.checkRegex(pathname.getAbsolutePath(), dangerousPatt)) {
                        accept = false;
                        Log.info("Skipped hazardous place: '" + pathname + "'");
                        break;
                    }
                }
            } else {
                accept = false;
            }
            return accept;
        });
        if (depth > 0 && subFolders != null) {
            for (File subFolder : subFolders) { // FIXED avoid NPE on (protected) subFolders if custom dir.
                if (JFrameMain.isCLOSING_APP()) {
                    break;
                }
                files.add(subFolder);
                listDirNoRecount(jframe, files, subFolder, depth - 1, dangerousFolders);
            }
        }
    }
    
    /**
     * Check if a file-name verifies one of the patterns in the patterns-collection.
     *
     * @param file the file to check.
     * @param redistsPatterns the patterns-collection.
     * @return the file if it verifies a pattern, otherwise null.
     */
    public static Redist checkFile(File file, List<Redist> redistsPatterns) {
        Redist checkedFiles = null;
        for (Redist redist : redistsPatterns) {
            Pattern pattern = redist.getCompiledPattern();
            String fileName = file.getName();
            if (pattern.matcher(fileName).find()) {
                checkedFiles = new Redist(file, redist.getDescription());
                break;
            }
        }
        return checkedFiles;
    }
    
    /**
     * Delete a folder on the hard-drive.
     *
     * @param folder the folder to delete.
     * @return true if deletion is successful, otherwise false.
     */
    public static boolean deleteFolder(File folder) {
        boolean deleted;
        try {
            if (folder.exists()) {
                org.apache.commons.io.FileUtils.deleteDirectory(folder);
            }
            deleted = true;
        } catch (IOException ex) {
            Log.error(ex);
            deleted = false;
        }
        return deleted;
    }
}

@@ -132,31 +132,8 @@
 ain;
-%0A%0Aimport javax.swing.*;
 %0Aimp
@@ -261,16 +261,38 @@
 Pattern;
+%0Aimport javax.swing.*;
 %0A%0A/**%0A *
@@ -1241,32 +1241,368 @@
           try %7B%0A
+%09%09%09%09%09%09%09%09%09if (!folder.exists()) %7B%0A%09%09%09%09%09%09%09%09%09%09%09Log.info(%22Skipped path: '%22 + folder.getAbsolutePath() + %22', this path doesn't exist%22);%0A%09%09%09%09%09%09%09%09%09%09%09continue;%0A%09%09%09%09%09%09%09%09%09%7D%0A%09%09%09%09%09%09%09%09%09if (!folder.isDirectory()) %7B%0A%09%09%09%09%09%09%09%09%09%09%09Log.info(%22Skipped path: '%22 + folder.getAbsolutePath() + %22', this path is not a directory%22);%0A%09%09%09%09%09%09%09%09%09%09%09continue;%0A%09%09%09%09%09%09%09%09%09%7D%0A
                 

improve log message if a directory can't be opened