/*
 * 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.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>&nbsp;</p>
     * the touch is basically just the same as unix touch
     *
     * @param fileToTouch the file which needs unix style touching
     */
    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;
    }

    /**
     * Gets a temp dir to work on
     * @return a temp dir which can be used for io processing
     */
    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();
            }
        } */
        if(!tempDir.exists()) {
            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
     * &lt;path&gt;/&lt;appendix&gt;;...
     *
     * @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;
    }
}
