/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.io;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.io.filefilter.NameFileFilter;
import org.apache.commons.io.filefilter.OrFileFilter;
import org.junit.jupiter.api.Test;

/**
 * This is used to test DirectoryWalker for correctness when using Java4 (i.e. no generics).
 *
 * @see DirectoryWalker
 */
@SuppressWarnings({"unchecked", "rawtypes"}) // Java4
public class DirectoryWalkerTestCaseJava4 {

    // Directories
    private static final File current = new File(".");
    private static final File javaDir = new File("src/main/java");
    private static final File orgDir = new File(javaDir, "org");
    private static final File apacheDir = new File(orgDir, "apache");
    private static final File commonsDir = new File(apacheDir, "commons");
    private static final File ioDir = new File(commonsDir, "io");
    private static final File outputDir = new File(ioDir, "output");
    private static final File[] dirs = new File[]{orgDir, apacheDir, commonsDir, ioDir, outputDir};

    // Files
    private static final File filenameUtils = new File(ioDir, "FilenameUtils.java");
    private static final File ioUtils = new File(ioDir, "IOUtils.java");
    private static final File proxyWriter = new File(outputDir, "ProxyWriter.java");
    private static final File nullStream = new File(outputDir, "NullOutputStream.java");
    private static final File[] ioFiles = new File[]{filenameUtils, ioUtils};
    private static final File[] outputFiles = new File[]{proxyWriter, nullStream};

    // Filters
    private static final IOFileFilter dirsFilter = createNameFilter(dirs);
    private static final IOFileFilter iofilesFilter = createNameFilter(ioFiles);
    private static final IOFileFilter outputFilesFilter = createNameFilter(outputFiles);
    private static final IOFileFilter ioDirAndFilesFilter = new OrFileFilter(dirsFilter, iofilesFilter);
    private static final IOFileFilter dirsAndFilesFilter = new OrFileFilter(ioDirAndFilesFilter, outputFilesFilter);

    // Filter to exclude SVN files
    private static final IOFileFilter NOT_SVN = FileFilterUtils.makeSVNAware(null);

    //-----------------------------------------------------------------------

    /**
     * Test Filtering
     */
    @Test
    public void testFilter() {
        final List<File> results = new TestFileFinder(dirsAndFilesFilter, -1).find(javaDir);
        assertEquals(1 + dirs.length + ioFiles.length + outputFiles.length, results.size(), "Result Size");
        assertTrue(results.contains(javaDir), "Start Dir");
        checkContainsFiles("Dir", dirs, results);
        checkContainsFiles("IO File", ioFiles, results);
        checkContainsFiles("Output File", outputFiles, results);
    }

    /**
     * Test Filtering and limit to depth 0
     */
    @Test
    public void testFilterAndLimitA() {
        final List<File> results = new TestFileFinder(NOT_SVN, 0).find(javaDir);
        assertEquals(1, results.size(), "[A] Result Size");
        assertTrue(results.contains(javaDir), "[A] Start Dir");
    }

    /**
     * Test Filtering and limit to depth 1
     */
    @Test
    public void testFilterAndLimitB() {
        final List<File> results = new TestFileFinder(NOT_SVN, 1).find(javaDir);
        assertEquals(2, results.size(), "[B] Result Size");
        assertTrue(results.contains(javaDir), "[B] Start Dir");
        assertTrue(results.contains(orgDir), "[B] Org Dir");
    }

    /**
     * Test Filtering and limit to depth 3
     */
    @Test
    public void testFilterAndLimitC() {
        final List<File> results = new TestFileFinder(NOT_SVN, 3).find(javaDir);
        assertEquals(4, results.size(), "[C] Result Size");
        assertTrue(results.contains(javaDir), "[C] Start Dir");
        assertTrue(results.contains(orgDir), "[C] Org Dir");
        assertTrue(results.contains(apacheDir), "[C] Apache Dir");
        assertTrue(results.contains(commonsDir), "[C] Commons Dir");
    }

    /**
     * Test Filtering and limit to depth 5
     */
    @Test
    public void testFilterAndLimitD() {
        final List<File> results = new TestFileFinder(dirsAndFilesFilter, 5).find(javaDir);
        assertEquals(1 + dirs.length + ioFiles.length, results.size(), "[D] Result Size");
        assertTrue(results.contains(javaDir), "[D] Start Dir");
        checkContainsFiles("[D] Dir", dirs, results);
        checkContainsFiles("[D] File", ioFiles, results);
    }

    /**
     * Test separate dir and file filters
     */
    @Test
    public void testFilterDirAndFile1() {
        final List<File> results = new TestFileFinder(dirsFilter, iofilesFilter, -1).find(javaDir);
        assertEquals(1 + dirs.length + ioFiles.length, results.size(), "[DirAndFile1] Result Size");
        assertTrue(results.contains(javaDir), "[DirAndFile1] Start Dir");
        checkContainsFiles("[DirAndFile1] Dir", dirs, results);
        checkContainsFiles("[DirAndFile1] File", ioFiles, results);
    }

    /**
     * Test separate dir and file filters
     */
    @Test
    public void testFilterDirAndFile2() {
        final List<File> results = new TestFileFinder(null, null, -1).find(javaDir);
        assertTrue(results.size() > 1 + dirs.length + ioFiles.length, "[DirAndFile2] Result Size");
        assertTrue(results.contains(javaDir), "[DirAndFile2] Start Dir");
        checkContainsFiles("[DirAndFile2] Dir", dirs, results);
        checkContainsFiles("[DirAndFile2] File", ioFiles, results);
    }

    /**
     * Test separate dir and file filters
     */
    @Test
    public void testFilterDirAndFile3() {
        final List<File> results = new TestFileFinder(dirsFilter, null, -1).find(javaDir);
        final List resultDirs = directoriesOnly(results);
        assertEquals(1 + dirs.length, resultDirs.size(), "[DirAndFile3] Result Size");
        assertTrue(results.contains(javaDir), "[DirAndFile3] Start Dir");
        checkContainsFiles("[DirAndFile3] Dir", dirs, resultDirs);
    }

    /**
     * Test separate dir and file filters
     */
    @Test
    public void testFilterDirAndFile4() {
        final List<File> results = new TestFileFinder(null, iofilesFilter, -1).find(javaDir);
        final List resultFiles = filesOnly(results);
        assertEquals(ioFiles.length, resultFiles.size(), "[DirAndFile4] Result Size");
        assertTrue(results.contains(javaDir), "[DirAndFile4] Start Dir");
        checkContainsFiles("[DirAndFile4] File", ioFiles, resultFiles);
    }

    /**
     * Test Limiting to current directory
     */
    @Test
    public void testLimitToCurrent() {
        final List<File> results = new TestFileFinder(null, 0).find(current);
        assertEquals(1, results.size(), "Result Size");
        assertTrue(results.contains(new File(".")), "Current Dir");
    }

    /**
     * test an invalid start directory
     */
    @Test
    public void testMissingStartDirectory() {

        // TODO is this what we want with invalid directory?
        final File invalidDir = new File("invalid-dir");
        final List<File> results = new TestFileFinder(null, -1).find(invalidDir);
        assertEquals(1, results.size(), "Result Size");
        assertTrue(results.contains(invalidDir), "Current Dir");

        try {
            new TestFileFinder(null, -1).find(null);
            fail("Null start directory didn't throw Exception");
        } catch (final NullPointerException ignore) {
            // expected result
        }
    }

    /**
     * test an invalid start directory
     */
    @Test
    public void testHandleStartDirectoryFalse() {

        final List<File> results = new TestFalseFileFinder(null, -1).find(current);
        assertEquals(0, results.size(), "Result Size");

    }

    // ------------ Convenience Test Methods ------------------------------------

    /**
     * Check the files in the array are in the results list.
     */
    private void checkContainsFiles(final String prefix, final File[] files, final Collection results) {
        for (int i = 0; i < files.length; i++) {
            assertTrue(results.contains(files[i]), prefix + "[" + i + "] " + files[i]);
        }
    }

    /**
     * Extract the directories.
     */
    private List directoriesOnly(final Collection<File> results) {
        final List list = new ArrayList(results.size());
        for (final File file : results) {
            if (file.isDirectory()) {
                list.add(file);
            }
        }
        return list;
    }

    /**
     * Extract the files.
     */
    private List filesOnly(final Collection<File> results) {
        final List list = new ArrayList(results.size());
        for (final File file : results) {
            if (file.isFile()) {
                list.add(file);
            }
        }
        return list;
    }

    /**
     * Create a name filter containing the names of the files
     * in the array.
     */
    private static IOFileFilter createNameFilter(final File[] files) {
        final String[] names = new String[files.length];
        for (int i = 0; i < files.length; i++) {
            names[i] = files[i].getName();
        }
        return new NameFileFilter(names);
    }

    /**
     * Test Cancel
     * @throws IOException
     */
    @Test
    public void testCancel() throws IOException {
        String cancelName = null;

        // Cancel on a file
        try {
            cancelName = "DirectoryWalker.java";
            new TestCancelWalker(cancelName, false).find(javaDir);
            fail("CancelException not thrown for '" + cancelName + "'");
        } catch (final DirectoryWalker.CancelException cancel) {
            assertEquals(cancelName, cancel.getFile().getName(), "File:  " + cancelName);
            assertEquals(5, cancel.getDepth(), "Depth: " + cancelName);
        }

        // Cancel on a directory
        try {
            cancelName = "commons";
            new TestCancelWalker(cancelName, false).find(javaDir);
            fail("CancelException not thrown for '" + cancelName + "'");
        } catch (final DirectoryWalker.CancelException cancel) {
            assertEquals(cancelName, cancel.getFile().getName(), "File:  " + cancelName);
            assertEquals(3, cancel.getDepth(), "Depth: " + cancelName);
        }

        // Suppress CancelException (use same file name as preceding test)
        final List results = new TestCancelWalker(cancelName, true).find(javaDir);
        final File lastFile = (File) results.get(results.size() - 1);
        assertEquals(cancelName, lastFile.getName(), "Suppress:  " + cancelName);
    }

    /**
     * Test Cancel
     * @throws IOException
     */
    @Test
    public void testMultiThreadCancel() throws IOException {
        String cancelName = "DirectoryWalker.java";
        TestMultiThreadCancelWalker walker = new TestMultiThreadCancelWalker(cancelName, false);
        // Cancel on a file
        try {
            walker.find(javaDir);
            fail("CancelException not thrown for '" + cancelName + "'");
        } catch (final DirectoryWalker.CancelException cancel) {
            final File last = (File) walker.results.get(walker.results.size() - 1);
            assertEquals(cancelName, last.getName());
            assertEquals(5, cancel.getDepth(), "Depth: " + cancelName);
        }

        // Cancel on a directory
        try {
            cancelName = "commons";
            walker = new TestMultiThreadCancelWalker(cancelName, false);
            walker.find(javaDir);
            fail("CancelException not thrown for '" + cancelName + "'");
        } catch (final DirectoryWalker.CancelException cancel) {
            assertEquals(cancelName, cancel.getFile().getName(), "File:  " + cancelName);
            assertEquals(3, cancel.getDepth(), "Depth: " + cancelName);
        }

        // Suppress CancelException (use same file name as preceding test)
        walker = new TestMultiThreadCancelWalker(cancelName, true);
        final List results = walker.find(javaDir);
        final File lastFile = (File) results.get(results.size() - 1);
        assertEquals(cancelName, lastFile.getName(), "Suppress:  " + cancelName);

    }

    // ------------ Test DirectoryWalker implementation --------------------------

    /**
     * Test DirectoryWalker implementation that finds files in a directory hierarchy
     * applying a file filter.
     */
    private static class TestFileFinder extends DirectoryWalker {

        protected TestFileFinder(final FileFilter filter, final int depthLimit) {
            super(filter, depthLimit);
        }

        protected TestFileFinder(final IOFileFilter dirFilter, final IOFileFilter fileFilter, final int depthLimit) {
            super(dirFilter, fileFilter, depthLimit);
        }

        /**
         * find files.
         */
        protected List<File> find(final File startDirectory) {
            final List<File> results = new ArrayList<>();
            try {
                walk(startDirectory, results);
            } catch (final IOException ex) {
                fail(ex.toString());
            }
            return results;
        }

        /**
         * Handles a directory end by adding the File to the result set.
         */
        @Override
        protected void handleDirectoryEnd(final File directory, final int depth, final Collection results) {
            results.add(directory);
        }

        /**
         * Handles a file by adding the File to the result set.
         */
        @Override
        protected void handleFile(final File file, final int depth, final Collection results) {
            results.add(file);
        }
    }

    // ------------ Test DirectoryWalker implementation --------------------------

    /**
     * Test DirectoryWalker implementation that always returns false
     * from handleDirectoryStart()
     */
    private static class TestFalseFileFinder extends TestFileFinder {

        protected TestFalseFileFinder(final FileFilter filter, final int depthLimit) {
            super(filter, depthLimit);
        }

        /**
         * Always returns false.
         */
        @Override
        protected boolean handleDirectory(final File directory, final int depth, final Collection results) {
            return false;
        }
    }

    // ------------ Test DirectoryWalker implementation --------------------------

    /**
     * Test DirectoryWalker implementation that finds files in a directory hierarchy
     * applying a file filter.
     */
    static class TestCancelWalker extends DirectoryWalker {
        private final String cancelFileName;
        private final boolean suppressCancel;

        TestCancelWalker(final String cancelFileName, final boolean suppressCancel) {
            this.cancelFileName = cancelFileName;
            this.suppressCancel = suppressCancel;
        }

        /**
         * find files.
         */
        protected List find(final File startDirectory) throws IOException {
            final List results = new ArrayList();
            walk(startDirectory, results);
            return results;
        }

        /**
         * Handles a directory end by adding the File to the result set.
         */
        @Override
        protected void handleDirectoryEnd(final File directory, final int depth, final Collection results) throws IOException {
            results.add(directory);
            if (cancelFileName.equals(directory.getName())) {
                throw new CancelException(directory, depth);
            }
        }

        /**
         * Handles a file by adding the File to the result set.
         */
        @Override
        protected void handleFile(final File file, final int depth, final Collection results) throws IOException {
            results.add(file);
            if (cancelFileName.equals(file.getName())) {
                throw new CancelException(file, depth);
            }
        }

        /**
         * Handles Cancel.
         */
        @Override
        protected void handleCancelled(final File startDirectory, final Collection results,
                                       final CancelException cancel) throws IOException {
            if (!suppressCancel) {
                super.handleCancelled(startDirectory, results, cancel);
            }
        }
    }

    /**
     * Test DirectoryWalker implementation that finds files in a directory hierarchy
     * applying a file filter.
     */
    static class TestMultiThreadCancelWalker extends DirectoryWalker {
        private final String cancelFileName;
        private final boolean suppressCancel;
        private boolean cancelled;
        public List results;

        TestMultiThreadCancelWalker(final String cancelFileName, final boolean suppressCancel) {
            this.cancelFileName = cancelFileName;
            this.suppressCancel = suppressCancel;
        }

        /**
         * find files.
         */
        protected List find(final File startDirectory) throws IOException {
            results = new ArrayList();
            walk(startDirectory, results);
            return results;
        }

        /**
         * Handles a directory end by adding the File to the result set.
         */
        @Override
        protected void handleDirectoryEnd(final File directory, final int depth, final Collection results) throws IOException {
            results.add(directory);
            assertFalse(cancelled);
            if (cancelFileName.equals(directory.getName())) {
                cancelled = true;
            }
        }

        /**
         * Handles a file by adding the File to the result set.
         */
        @Override
        protected void handleFile(final File file, final int depth, final Collection results) throws IOException {
            results.add(file);
            assertFalse(cancelled);
            if (cancelFileName.equals(file.getName())) {
                cancelled = true;
            }
        }

        /**
         * Handles Cancelled.
         */
        @Override
        protected boolean handleIsCancelled(final File file, final int depth, final Collection results) throws IOException {
            return cancelled;
        }

        /**
         * Handles Cancel.
         */
        @Override
        protected void handleCancelled(final File startDirectory, final Collection results,
                                       final CancelException cancel) throws IOException {
            if (!suppressCancel) {
                super.handleCancelled(startDirectory, results, cancel);
            }
        }
    }

}
