/*
 * Autopsy Forensic Browser
 *
 * Copyright 2012-2015 Basis Technology Corp.
 * Contact: carrier <at> sleuthkit <dot> org
 *
 * Licensed 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.sleuthkit.autopsy.coreutils;

import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import org.openide.filesystems.FileObject;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.nio.file.Files;
import java.nio.file.Path;

/**
 * File and dir utilities
 */
public class FileUtil {

    private static final Logger logger = Logger.getLogger(FileUtil.class.getName());
    private static String TEMP_FILE_PREFIX = "Autopsy";

    /**
     * Recursively delete all of the files and sub-directories in a directory.
     * Use deleteFileDir() if you are not sure if the path is a file or
     * directory.
     *
     * @param dirPath Path of the directory to delete
     *
     * @return true if the dir was deleted with no errors. False otherwise
     *         (including if the passed in path was for a file).
     */
    public static boolean deleteDir(File dirPath) {
        if (dirPath.isDirectory() == false || dirPath.exists() == false) {
            logger.log(Level.WARNING, "deleteDir passed in a non-directory: {0}", dirPath.getPath()); //NON-NLS
            return false;
        }

        File[] files = dirPath.listFiles();
        boolean hadErrors = false;
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    if (deleteDir(file) == false) {
                        // message was already logged
                        hadErrors = true;
                    }
                } else {
                    if (file.delete() == false) {
                        logger.log(Level.WARNING, "Failed to delete file {0}", file.getPath()); //NON-NLS
                        hadErrors = true;
                    }
                }
            }
        }
        if (dirPath.delete() == false) {
            logger.log(Level.WARNING, "Failed to delete the empty directory at {0}", dirPath.getPath()); //NON-NLS
            hadErrors = true;
        }

        return !hadErrors;
    }

    /**
     * Delete the file or dir at the given path. If the path is for a directory,
     * recursively delete its contents.
     *
     * @param path the path to the file or directory to delete
     *
     * @return true if the file or directory were deleted with no errors. False
     *         otherwise.
     */
    public static boolean deleteFileDir(File path) {
        boolean sucess = true;
        if (path.isFile()) { // If it's a file
            if (!path.delete()) {
                sucess = false;
                logger.log(Level.WARNING, "Failed to delete file {0}", path.getPath()); //NON-NLS
            }
        } else { // If it's a directory
            sucess = deleteDir(path);
        }
        return sucess;
    }

    /**
     * Copy a file to a new directory, potentially new file name, and overwrite
     * old one if requested
     *
     * @param source     source file path
     * @param destFolder destination folder path
     * @param newName    file name of the copied file, which can be different
     *                   from original
     * @param ext        file extension, e.g. ".java"
     * @param overwrite  if new file, already exists, overwrite it (delete it
     *                   first)
     *
     * @return path to the created file, or null if file was not created
     *
     * @throws IOException exception thrown if file copying failed
     */
    public static String copyFile(String source, String destFolder, String newName, String ext, boolean overwrite)
            throws IOException {

        final String destFileName = destFolder + File.separator + newName + ext;
        final File destFile = new File(destFileName);
        if (destFile.exists()) {
            if (overwrite) {
                destFile.delete();
            } else {
                return null;
            }
        }

        final FileObject sourceFileObj = org.openide.filesystems.FileUtil.createData(new File(source));
        final FileObject destFolderObj = org.openide.filesystems.FileUtil.createData(new File(destFolder));

        // org.openide.filesystems.FileUtil.copyFile requires an extension without the "." e.g. "java"
        FileObject created = org.openide.filesystems.FileUtil.copyFile(sourceFileObj, destFolderObj, newName, ext.substring(1));

        return created.getPath();

    }

    /**
     * Copy a folder into a new directory.
     *
     * @param source     path to the source folder
     * @param path       destination path of the new folder
     * @param folderName name of the new folder
     *
     * @return path to the new folder if created, null if it was not created
     *
     * @throws IOException exception thrown if file copying failed
     */
    public static String copyFolder(String source, String path, String folderName) throws IOException {
        String destFolder = path + File.separator + folderName;
        org.openide.filesystems.FileUtil.createFolder(new File(destFolder));

        final FileObject sourceFileObj = org.openide.filesystems.FileUtil.createData(new File(source));
        final FileObject destFolderObj = org.openide.filesystems.FileUtil.createData(new File(destFolder));

        FileObject created = org.openide.filesystems.FileUtil.copyFile(sourceFileObj, destFolderObj, sourceFileObj.getName(), sourceFileObj.getExt());

        return created.getPath();
    }

    /**
     * Escape special characters in a file name or a file name component
     *
     * @param fileName to escape
     *
     * @return escaped string
     */
    public static String escapeFileName(String fileName) {
        //for now escaping /:"*?<>| (not valid in file name, at least on Windows)
        //with underscores. We are only keeping \ as it could be part of the path.
        return fileName.replaceAll("[/:\"*?<>|]+", "_");
    }

    /**
     * Test if the current user has read and write access to the path.
     *
     * @param path The path to test for read and write access.
     *
     * @return True if we have both read and write access, false otherwise.
     */
    public static boolean hasReadWriteAccess(Path path) {
        Path p = null;
        try {
            p = Files.createTempFile(path, TEMP_FILE_PREFIX, null);
            return (p.toFile().canRead() && p.toFile().canWrite());
        } catch (IOException ex) {
            return false;
        } finally {
            if (p != null) {
                try {
                    p.toFile().delete();
                } catch (Exception ignored) {
                }
            }
        }
    }
}

@@ -850,93 +850,8 @@
 ct;%0A
-import java.io.BufferedReader;%0Aimport java.io.FileReader;%0Aimport java.io.FileWriter;%0A
 impo

remove unused imports