/*
 * 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.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;
    }
}
