/*
 * 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 rewrite.org.apache.myfaces.extensions.scripting.core.common.util;

import java.io.File;
import java.util.Collection;
import java.util.List;

/**
 * @author Werner Punz (latest modification by $Author$)
 * @version $Revision$ $Date$
 */

public class FileUtils {
    static double _tempMarker = Math.random();

    /**
     * Get the file separator for this platform.
     *
     * @return The file separator.
     */
    public static String getFileSeparator() {
        return File.separator;
    }

    /**
     * touch functionality to mark
     * compiles and dependencies as changed
     * to get a clean reloading state
     * <p/>
     * the touch is basically just the same as unix touch
     *
     * @param fileToTouch
     */
    public static void touch(File fileToTouch) {
        //we change our lastMofied to the current system time
        if (!fileToTouch.exists()) return;
        fileToTouch.setLastModified(System.currentTimeMillis());
    }

    /**
     * Get the file separator for this platform, properly escaped for usage in a regular expression.
     * workaround for http://bugs.sun.com/view_bug.do?bug_id=4626653 another workaround would be
     * to use the Matcher.quoteReplacement as of http://bugs.sun.com/view_bug.do?bug_id=5024613  instead
     * of using String.replaceAll
     *
     * @return The file separator, escaped for in a regex.
     */
    public static String getFileSeparatorForRegex() {
        String sep = getFileSeparator();

        if ("\\".equals(sep)) {
            sep = "\\\\";
        }

        return sep;
    }

    public static File getTempDir() {
        File tempDir;

        String baseTempPath = System.getProperty("java.io.tmpdir");
        String tempDirName = "myfaces_compilation_"; //+ _tempMarker;

        tempDir = new File(baseTempPath + File.separator + tempDirName);
        /*while (tempDir.exists()) {
            tempDirName = "myfaces_compilation_" + System.currentTimeMillis() + Math.random();
            tempDir = new File(baseTempPath + File.separator + tempDirName);
        }

        synchronized (FileUtils.class) {
            if (tempDir.exists()) {
                return tempDir;
            }
            if (tempDir.mkdirs()) {
                tempDir.deleteOnExit();
            }
        } */
        return tempDir;
    }

    /**
     * we roll our own tree walker here
     * to avoid a dependency into commons fileutils
     * and to apply an easier pattern than
     * commons fileutils uses
     *
     * @param rootDir  the root dir for our walking
     * @param strategy the strategy to apply to for our walking
     */
    public static void listFiles(File rootDir, Strategy strategy) {
        if (!rootDir.isDirectory()) {
            strategy.apply(rootDir);
            return;
        }

        File[] files = rootDir.listFiles();
        for (File file : files) {
            boolean isDirectory = file.isDirectory();
            if (isDirectory && !file.getName().endsWith(".")) {
                listFiles(file, strategy);
                strategy.apply(file);
            } else if (!isDirectory) {
                strategy.apply(file);
            }
        }
    }

    /**
     * <p>
     * target path check to check if the targetPath is valid or can be created
     * </p>
     *
     * @param path the path to be investigated
     */
    public static void assertPath(File path) {
        // The destination directory must already exist as javac will not create the destination directory.
        if (!path.exists()) {
            if (!path.mkdirs()) {
                throw new IllegalStateException("It wasn't possible to create the target " +
                        "directory for the compiler ['" + path.getAbsolutePath() + "'].");
            }

            // If we've created the destination directory, we'll delete it as well once the application exits
            path.deleteOnExit();
        }
    }

    /**
     * fetches recursively the files under the current root
     *
     * @param sourcePath the source path from which the walker should start from
     * @param fileType   the pattern upon which the file has to be matched to aka *.java etc...
     * @return a list of source files
     */
    public static List<File> fetchSourceFiles(File sourcePath, String fileType) {
        FileStrategy strategy = new FileStrategy(fileType);
        listFiles(sourcePath, strategy);

        return strategy.getFoundFiles();
    }

    /**
     * fetches the source files from a list of source paths
     *
     * @param sourcePaths the collection of paths to be searched for
     * @param fileType    the filetype to be searched for
     * @return a list of files found
     */
    public static List<File> fetchSourceFiles(Collection<String> sourcePaths, String fileType) {
        FileStrategy strategy = new FileStrategy(fileType);

        for (String sourcePath : sourcePaths) {
            File fSourcePath = new File(sourcePath);
            if (fSourcePath.exists()) {
                listFiles(fSourcePath, strategy);
            }
        }

        return strategy.getFoundFiles();
    }

    /**
     * fetches the source paths from a given root directory in the format
     * <path>/<appendix>;...
     *
     * @param sourcePath the sourcePath from which the directory traversal should happen from
     * @param appendix   the appendix which has to be appended to every path found
     * @return a string builder of the paths found
     */
    @SuppressWarnings("unused")
    public static StringBuilder fetchSourcePaths(File sourcePath, String appendix) {
        DirStrategy dirStrategy = new DirStrategy();
        StringBuilder sourcesList = new StringBuilder(512);

        listFiles(sourcePath, dirStrategy);
        for (File foundDir : dirStrategy.getFoundFiles()) {
            String dirName = foundDir.getAbsolutePath();
            sourcesList.append(dirName);
            sourcesList.append(File.separator);
            sourcesList.append(appendix);
        }
        return sourcesList;
    }
}
