package com.janosgyerik.duplicatefilefinder.finder;

import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class FileFinderImplTest {

    private static final FileFinder FINDER = new FileFinderImpl();

    private File createTempDir() throws IOException {
        File tempFile = File.createTempFile("tmp", "-dir");
        if (tempFile.delete() && tempFile.mkdir()) {
            return tempFile;
        }
        throw new IOException("could not create temporary directory");
    }

    private File createSubDir(File basedir, String name) throws IOException {
        File dir = new File(basedir, name);
        if (!dir.mkdir()) {
            throw new IOException("could not create directory: " + dir);
        }
        return dir;
    }

    private File createTempFile(File basedir) throws IOException {
        return createTempFile(basedir, ".tmp");
    }

    private File createTempFile(File basedir, String suffix) throws IOException {
        return File.createTempFile("tmp", suffix, basedir);
    }

    private List<File> sorted(File... files) {
        List<File> list = new ArrayList<>(Arrays.asList(files));
        Collections.sort(list);
        return list;
    }

    @Test
    public void test_find_nothing_in_empty_dir() throws IOException {
        File emptyDir = createTempDir();
        assertTrue(emptyDir.isDirectory());
        assertEquals(0, FINDER.find(emptyDir).size());
    }

    @Test
    public void test_find_one_file_in_basedir() throws IOException {
        File tempDir = createTempDir();
        File tempFile = createTempFile(tempDir);
        assertEquals(Collections.singletonList(tempFile), FINDER.find(tempDir));
    }

    @Test
    public void test_find_two_files_in_basedir() throws IOException {
        File tempDir = createTempDir();
        File tempFile1 = createTempFile(tempDir);
        File tempFile2 = createTempFile(tempDir);
        assertEquals(sorted(tempFile1, tempFile2), FINDER.find(tempDir));
    }

    @Test
    public void test_find_two_files_in_tree() throws IOException {
        File tempDir = createTempDir();
        File tempFile1 = createTempFile(tempDir);

        File subDir = createSubDir(tempDir, "sub1");
        File tempFile2 = createTempFile(subDir);

        assertEquals(sorted(tempFile1, tempFile2), FINDER.find(tempDir));
    }

    @Test
    public void test_find_one_file_until_depth() throws IOException {
        File tempDir = createTempDir();
        File tempFile1 = createTempFile(tempDir);

        File subDir = createSubDir(tempDir, "sub1");
        File tempFile2 = createTempFile(subDir);

        assertEquals(sorted(tempFile1, tempFile2), FINDER.find(tempDir));
        assertEquals(sorted(tempFile1), FINDER.find(tempDir, 1));
    }

    @Test
    public void test_find_one_file_matching_extension() throws IOException {
        File tempDir = createTempDir();

        final String suffix = ".tmp";
        File tempFile1 = createTempFile(tempDir, suffix);
        File tempFile2 = createTempFile(tempDir, ".exe");
        assertEquals(sorted(tempFile1, tempFile2), FINDER.find(tempDir));

        assertEquals(sorted(tempFile1), FINDER.find(tempDir, pathname -> {
            return pathname.getName().endsWith(suffix);
        }));
    }

    @Test
    public void test_find_one_file_until_accessible() throws IOException {
        File tempDir = createTempDir();
        File tempFile1 = createTempFile(tempDir);

        File subDir = createSubDir(tempDir, "sub1");
        File tempFile2 = createTempFile(subDir);

        assertEquals(sorted(tempFile1, tempFile2), FINDER.find(tempDir));

        if (!subDir.setExecutable(false)) {
            throw new IOException("could not revoke directory executable permission");
        }
        assertEquals(sorted(tempFile1), FINDER.find(tempDir, 1));

        if (!subDir.setExecutable(true)) {
            throw new IOException("could not restore directory executable permission");
        }
        assertEquals(sorted(tempFile1, tempFile2), FINDER.find(tempDir));
    }
}

@@ -119,16 +119,44 @@
 eption;%0A
+import java.nio.file.Files;%0A
 import j
@@ -521,19 +521,19 @@
 temp
-File
+Dir
  = File
+s
 .cre
@@ -543,431 +543,282 @@
 Temp
-File(%22tmp%22, %22-dir%22);%0A        if (tempFile.delete() && tempFile.mkdir()) %7B%0A            return tempFile;%0A        %7D%0A        throw new IOException(%22could not create temporary directory%22);%0A    %7D%0A%0A    private File createSubDir(File basedir, String name) throws IOException %7B%0A        File dir = new File(basedir, name);%0A        if (!dir.mkdir()) %7B%0A            throw new IOException(%22could not create directory: %22 + dir);%0A        %7D
+Directory(%22tmp%22).toFile();%0A        tempDir.deleteOnExit();%0A        return tempDir;%0A    %7D%0A%0A    private File createSubDir(File basedir, String name) throws IOException %7B%0A        File dir = Files.createTempDirectory(basedir.toPath(), name).toFile();%0A        dir.deleteOnExit();
 %0A   
@@ -1053,22 +1053,27 @@
         
-return
+File file =
  File.cr
@@ -1106,24 +1106,74 @@
 , basedir);%0A
+        file.deleteOnExit();%0A        return file;%0A
     %7D%0A%0A    p

delete temp files on exit