/*
* Copyright (C) 2012 The Android Open Source Project
*
* 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 com.motorola.studio.android.common.utilities;

import static com.motorola.studio.android.common.log.StudioLogger.warn;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.editors.text.TextFileDocumentProvider;

import com.motorola.studio.android.common.CommonPlugin;
import com.motorola.studio.android.common.log.StudioLogger;
import com.motorola.studio.android.common.utilities.i18n.UtilitiesNLS;

/**
 * DESCRIPTION: This class provides utility methods to handle files, like
 * copying and deleting directories sub-trees.
 * 
 * USAGE: See public methods
 */
public class FileUtil
{
    public static final int OS_WINDOWS = 0;

    public static final int OS_LINUX = 1;

    public static final char[] MAC_SPECIAL_CHAR =
    {
            '\\', ' ', '\'', '"', '!', '@', '$', '&', '*', '(', ')', '=', '`', '[', ']', '{', '}',
            '^', '<', '>', ':', ';', '?', '|'
    };

    public static final char[] LINUX_SPECIAL_CHAR =
    {
            '\\', ' ', '\'', '"', '!', '$', '&', '*', '(', ')', '=', '`', '[', ']', '{', '}', '^',
            '<', '>', ':', ';', '?', '|'
    };

    public static final char ESCAPE_CHAR = '\\';

    private static final int BUFFER_SIZE = 1024;

    /**
     * Copy full list of contents from a directory to another. The source
     * directory is not created within the target one.
     *
     * @param fromDir
     *           Source directory.
     * @param toDir
     *           Target directory.
     *           
     * @param IOException if I/O occurs         
     */
    public static void copyDir(File fromDir, File toDir) throws IOException
    {
        if ((fromDir != null) && fromDir.isDirectory() && fromDir.canRead() && (toDir != null)
                && toDir.isDirectory() && toDir.canWrite())
        {
            for (File child : fromDir.listFiles())
            {
                if (child.isFile())
                {
                    copyFile(child, new File(toDir, child.getName()));
                }
                else
                {
                    // create directory and copy its children recursively
                    File newDir = new File(toDir.getAbsolutePath(), child.getName());
                    newDir.mkdir();
                    copyDir(child, newDir);
                }
            }

            StudioLogger.info("The directory " + fromDir.getName() + " was successfully copied to " //$NON-NLS-1$ //$NON-NLS-2$
                    + toDir.getName() + "."); //$NON-NLS-1$

        }
        else
        {
            //error detected 
            String errorMessage = ""; //$NON-NLS-1$
            if (fromDir == null)
            {
                errorMessage = "Null pointer for source directory."; //$NON-NLS-1$
            }
            else
            {
                if (!fromDir.isDirectory())
                {
                    errorMessage = fromDir.getName() + " is not a directory."; //$NON-NLS-1$
                }
                else
                {
                    if (!fromDir.canRead())
                    {
                        errorMessage = "Cannot read from " + fromDir.getName() + "."; //$NON-NLS-1$ //$NON-NLS-2$
                    }
                    else
                    {
                        if (toDir == null)
                        {
                            errorMessage = "Null pointer for destination directory."; //$NON-NLS-1$
                        }
                        else
                        {
                            if (!toDir.isDirectory())
                            {
                                errorMessage = toDir.getName() + " is not a directory."; //$NON-NLS-1$
                            }
                            else
                            {
                                if (!toDir.canWrite())
                                {
                                    errorMessage = "Cannot write to" + toDir.getName() + "."; //$NON-NLS-1$ //$NON-NLS-2$
                                }
                            }
                        }
                    }
                }
            }
            StudioLogger.error(errorMessage);
            throw new IOException("Error copying directory: " + errorMessage); //$NON-NLS-1$
        }
    }

    /**
     * Copies the source file to the given target.
     *
     * @param source -
     *           the absolute path of the source file.
     * @param target -
     *           the absolute path of the target file.
     */
    public static void copyFile(File source, File target) throws IOException
    {
        copyFile(source.getAbsolutePath(), target.getAbsolutePath());
    }

    /**
     * Copies the source file to the given target.
     *
     * @param source -
     *           the absolute path of the source file.
     * @param target -
     *           the absolute path of the target file.
     */
    private static void copyFile(String source, String target) throws IOException
    {
        FileChannel sourceFileChannel = null;
        FileChannel targetFileChannel = null;
        FileInputStream sourceFileInStream = null;
        FileOutputStream targetFileOutStream = null;
        try
        {
            sourceFileInStream = new FileInputStream(source);
            sourceFileChannel = sourceFileInStream.getChannel();
            targetFileOutStream = new FileOutputStream(target);
            targetFileChannel = targetFileOutStream.getChannel();
            targetFileChannel.transferFrom(sourceFileChannel, 0, sourceFileChannel.size());
            StudioLogger.info("The file " + source + " was successfully copied to " + target + "."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        }
        catch (IOException e)
        {
            StudioLogger.error("Error copying file" + source + "to " + target + "."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            throw e;
        }
        finally
        {
            try
            {
                if (sourceFileChannel != null)
                {
                    sourceFileChannel.close();
                }
            }
            catch (IOException e)
            {
                StudioLogger.error("Error closing file " + source + "."); //$NON-NLS-1$ //$NON-NLS-2$
                throw e;
            }

            try
            {
                if (targetFileChannel != null)
                {
                    targetFileChannel.close();
                }
            }
            catch (IOException e)
            {
                StudioLogger.error("Error closing file" + target + "."); //$NON-NLS-1$ //$NON-NLS-2$
                throw e;
            }

            try
            {
                if (sourceFileInStream != null)
                {
                    sourceFileInStream.close();
                }
            }
            catch (IOException e)
            {
                StudioLogger.error("Error closing file" + source + "."); //$NON-NLS-1$ //$NON-NLS-2$
                throw e;
            }

            try
            {
                if (targetFileOutStream != null)
                {
                    targetFileOutStream.close();
                }
            }
            catch (IOException e)
            {
                StudioLogger.error("Error closing file" + target + "."); //$NON-NLS-1$ //$NON-NLS-2$
                throw e;
            }

        }
    }

    /**
     * This method deletes the directory, all files and all subdirectories under
     * it. If a deletion fails, the method stops attempting to delete and
     * returns false.
     *
     * @param directory
     *           The directory to be deleted
     * @return Returns true if all deletions were successful. If the directory
     *         doesn't exist returns false.
     * @throws IOException
     *            When the parameter isn't a directory
     */
    public static boolean deleteDirRecursively(File directory) throws IOException
    {
        String dirName = ""; //$NON-NLS-1$

        boolean success = true;

        if (directory.exists())
        {
            if (directory.isDirectory())
            {
                dirName = directory.getName();
                File[] children = directory.listFiles();

                for (File element : children)
                {
                    if (element.isFile())
                    {
                        success = success && element.delete();
                    }
                    else
                    {
                        success = success && deleteDirRecursively(element);
                    }
                }

                success = success && directory.delete();
            }
            else
            {
                String errorMessage = directory.getName() + " is not a diretory."; //$NON-NLS-1$
                StudioLogger.error(errorMessage);
                throw new IOException(errorMessage);
            }
        }
        else
        {
            String errorMessage = "The directory does not exist."; //$NON-NLS-1$
            StudioLogger.error(errorMessage);
            success = false;
            throw new IOException(errorMessage);
        }

        if ((success) && (!dirName.equals(""))) //$NON-NLS-1$
        {
            StudioLogger.info("The directory " + dirName + "was successfully deleted."); //$NON-NLS-1$ //$NON-NLS-2$
        }

        return success;
    }

    /**
     * Delete a single file from the filesystem.
     *
     * @param fileToDelete
     *           A <code>File</code> object representing the file to be
     *           deleted.
     * @throws IOException
     *            if any problem occurs deleting the file.
     */
    public static void deleteFile(File fileToDelete) throws IOException
    {
        if ((fileToDelete != null) && fileToDelete.exists() && fileToDelete.isFile()
                && fileToDelete.canWrite())
        {
            fileToDelete.delete();
            StudioLogger.info("The file " + fileToDelete.getName() + "was successfully deleted."); //$NON-NLS-1$ //$NON-NLS-2$
        }
        else
        {
            String errorMessage = ""; //$NON-NLS-1$
            if (fileToDelete == null)
            {
                errorMessage = "Null pointer for file to delete."; //$NON-NLS-1$
            }
            else
            {
                if (!fileToDelete.exists())
                {
                    errorMessage = "The file " + fileToDelete.getName() + " does not exist."; //$NON-NLS-1$ //$NON-NLS-2$
                }
                else
                {
                    if (!fileToDelete.isFile())
                    {
                        errorMessage = fileToDelete.getName() + " is not a file."; //$NON-NLS-1$
                    }
                    else
                    {
                        if (!fileToDelete.canWrite())
                        {
                            errorMessage = "Cannot write to " + fileToDelete.getName(); //$NON-NLS-1$
                        }
                    }
                }

            }

            StudioLogger.error(errorMessage);
            throw new IOException("Cannot delete file: " + errorMessage); //$NON-NLS-1$
        }
    }

    /**
     * Delete a list of files from the filesystem.
     *
     * @param filesToDelete
     *           A list of <code>File</code> objects representing the files
     *           to be deleted.
     * @throws IOException
     *            if any problem occurs deleting the files.
     */
    public static void deleteFilesOnList(List<File> filesToDelete) throws IOException
    {
        for (File element : filesToDelete)
        {
            if (element.exists())
            {
                deleteFile((element));
            }
        }
    }

    /**
     * Return the File Size in Bytes.
     * 
     * @param root The root File, it can be a directory
     * @return The size of the file in bytes
     * @throws IOException
     */
    public static int getFileSize(File root) throws IOException
    {
        int size = 0;
        if (root.isDirectory())
        {
            for (File child : root.listFiles())
            {
                size += FileUtil.getFileSize(child);
            }
        }
        else if (root.isFile())
        {
            FileInputStream fis = new FileInputStream(root);
            int available;
            try
            {
                available = fis.available();
            }
            finally
            {
                try
                {
                    fis.close();
                }
                catch (IOException e)
                {
                    //Do thing.
                }
            }
            size = available;
        }
        return size;
    }

    /**
     * getExtension(String fileName)
     *
     * @param fileName
     *           returns the extension of a given file. "extension" here means
     *           the final part of the string after the last dot.
     *
     * @return String containing the extension
     */
    public static String getExtension(String fileName)
    {
        if (fileName != null)
        {
            int i = fileName.lastIndexOf(".") + 1; //$NON-NLS-1$
            return (i == 0) ? "" : fileName.substring(i); //$NON-NLS-1$
        }
        else
        {
            StudioLogger.error("The file " + fileName + " does not exist."); //$NON-NLS-1$ //$NON-NLS-2$
            return null;
        }
    }

    /**
     * Get the list of all File objects that compose the path to the given File
     * object
     *
     * @param aFile
     *           the file whose path must be retrieved.
     * @return a List with all the File objects that compose the path to the
     *         given File object.
     */
    public static List<File> getFilesComposingPath(File aFile)
    {
        List<File> fileList;

        if (aFile == null)
        {
            fileList = new ArrayList<File>();
        }
        else
        {
            fileList = getFilesComposingPath(aFile.getParentFile());
            fileList.add(aFile);
        }

        return fileList;
    }

    /**
     * Retrieve the relative filename to access a targetFile from a homeFile
     * parent directory. Notice that to actualy use a relative File object you
     * must use the following new File(homeDir, relativeFilename) because using
     * only new File(relativeFilename) would give you a file whose directory is
     * the one set in the "user.dir" property.
     *
     * @param homeDir
     *           the directory from where you want to access the targetFile
     * @param targetFile
     *           the absolute file or dir that you want to access via relative
     *           filename from the homeFile
     * @return the relative filename that describes the location of the
     *         targetFile referenced from the homeFile dir
     * @throws IOException
     */
    public static String getRelativeFilename(File homeDir, File targetFile) throws IOException
    {
        StringBuffer relativePath = new StringBuffer();

        List<File> homeDirList = getFilesComposingPath(getCanonicalFile(homeDir));
        List<File> targetDirList = getFilesComposingPath(getCanonicalFile(targetFile));

        if (homeDirList.size() == 0)
        {
            StudioLogger.info("Home Dir has no parent."); //$NON-NLS-1$
        }

        if (targetDirList.size() == 0)
        {
            StudioLogger.info("Target Dir has no parent."); //$NON-NLS-1$
        }

        // get the index of the last common directory between sourceFile and
        // targetFile
        int commonIndex = -1;

        for (int i = 0; (i < homeDirList.size()) && (i < targetDirList.size()); i++)
        {
            File aHomeDir = homeDirList.get(i);
            File aTargetDir = targetDirList.get(i);

            if (aHomeDir.equals(aTargetDir))
            {
                commonIndex = i;
            }
            else
            {
                break;
            }
        }

        // return from all remaining directories of the homeFile
        for (int i = commonIndex + 1; i < homeDirList.size(); i++)
        {
            relativePath.append(".."); //$NON-NLS-1$
            relativePath.append(File.separatorChar);
        }

        // enter into all directories of the target file
        // stops when reachs the file name and extension
        for (int i = commonIndex + 1; i < targetDirList.size(); i++)
        {
            File targetDir = targetDirList.get(i);
            relativePath.append(targetDir.getName());

            if (i != (targetDirList.size() - 1))
            {
                relativePath.append(File.separatorChar);
            }
        }

        return relativePath.toString();
    }

    /**
     * Return a list of file absolute paths under "baseDir" and under its subdirectories,
     * recursively.
     *
     * @param baseDirToList
     *           A string that represents the BaseDir to initial search.
     * @return A List of filepaths of files under the "baseDir".
     * @throws IOException
     *            If the "baseDir" can not be read.
     */
    public static List<String> listFilesRecursively(String baseDirToList) throws IOException
    {
        File baseDirToListFiles = new File(baseDirToList);
        List<String> listOfFiles = listFilesRecursively(baseDirToListFiles);

        return listOfFiles;
    }

    /**
     * Return a list of file absolute paths under "baseDir" and under its subdirectories,
     * recursively.
     *
     * @param baseDirToList
     *           A file object that represents the "baseDir".
     * @return A List of filepaths of files under the "baseDir".
     * @throws IOException
     *            If the "baseDir" can not be read.
     */
    public static List<String> listFilesRecursively(File baseDirToList) throws IOException
    {
        List<String> listOfFiles = new ArrayList<String>();

        if (baseDirToList.exists() && baseDirToList.isDirectory() && baseDirToList.canRead())
        {
            File[] children = baseDirToList.listFiles();

            for (File child : children)
            {
                if (child.isFile())
                {
                    listOfFiles.add(child.getAbsolutePath());
                }
                else
                {
                    List<String> temporaryList = listFilesRecursively(child);
                    listOfFiles.addAll(temporaryList);
                }
            }
        }
        else
        {
            String errorMessage = ""; //$NON-NLS-1$
            if (!baseDirToList.exists())
            {
                errorMessage = "The base dir does not exist."; //$NON-NLS-1$
            }
            else
            {
                if (!baseDirToList.isDirectory())
                {
                    errorMessage = baseDirToList.getName() + "is not a directory."; //$NON-NLS-1$
                }
                else
                {
                    if (!baseDirToList.canRead())
                    {
                        errorMessage = "Cannot fread from " + baseDirToList.getName() + "."; //$NON-NLS-1$ //$NON-NLS-2$
                    }
                }
            }

            StudioLogger.error(errorMessage);
            throw new IOException("Error listing files: " + errorMessage); //$NON-NLS-1$
        }

        return listOfFiles;
    }

    /**
     * Calculate the canonical (an absolute filename without "\.\" and "\..\")
     * that describe the file described by the absoluteFilename.
     * @param absoluteFilename a file name that describe the full path of the file to use.
     * @return the canonical File objecta
     */
    public static File getCanonicalFile(String absoluteFilename)
    {
        return getCanonicalFile(new File(absoluteFilename));
    }

    /**
     * Calculate the canonical (an absolute filename without "\.\" and "\..\")
     * that describe the file described by the given location and filename.
     * @param location the directory of the file to be used
     * @param filename (or a relative filename) of the file to be used
     * @return the canonical File objecta
     */
    public static File getCanonicalFile(File location, String filename)
    {
        return getCanonicalFile(new File(location, filename));
    }

    /**
     * Calculate the canonical (an absolute filename without "\.\" and "\..\")
     * that describe the given file.
     * @param aFile the file whose cannonical path will be calculated
     * @return the canonical File objecta
     */
    public static File getCanonicalFile(File aFile)
    {
        File f = null;

        try
        {
            f = aFile.getCanonicalFile();
        }
        catch (IOException e)
        {
            // this should never happens
            StudioLogger.error(FileUtil.class, "FileUtil.getCanonicalFile: IOException e", e); //$NON-NLS-1$

            // since it's not possible to read from filesystem, return a File using String          
            String filename = aFile.getAbsolutePath();

            StringTokenizer st = new StringTokenizer(filename, File.separator);

            StringBuffer sb = new StringBuffer();

            while (st.hasMoreTokens())
            {
                String token = (String) st.nextElement();

                if (token.equals("..")) //$NON-NLS-1$
                {
                    int lastDirIndex = sb.lastIndexOf(File.separator);

                    // do not go back currently on the root directory
                    if (lastDirIndex > 2)
                    {
                        sb.delete(lastDirIndex, sb.length());
                    }
                }
                else if (!token.equals(".")) //$NON-NLS-1$
                {
                    if (sb.length() > 0)
                    {
                        sb.append(File.separator);
                    }

                    sb.append(token);

                    if (token.endsWith(":")) //$NON-NLS-1$
                    {
                        sb.append(File.separator);
                    }
                }
            }

            f = new File(sb.toString());
        }

        return f;
    }

    /**
     * Returns which is the OS.
     * @return
     *      a code corresponding to the proper OS
     */
    public static int getOS()
    {
        int result = -1;

        String osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$
        if (osName.indexOf("linux") > -1) //$NON-NLS-1$
        {
            result = OS_LINUX;
        }
        else if (osName.indexOf("windows") > -1) //$NON-NLS-1$
        {
            result = OS_WINDOWS;
        }

        return result;
    }

    /**
     *   Returns true if the OS is windows
     * @return true if the OS is windows
     */
    public static boolean isWindows()
    {
        return getOS() == OS_WINDOWS;
    }

    /**
     * Opens the stream;
     *
     * @param stream File Stream
     *
     * @return StringBuffer with the file content
     *
     * @throws IOException
     */
    public static StringBuffer openFile(InputStream stream) throws IOException
    {
        InputStreamReader streamReader = null;
        StringBuffer fileBuffer = new StringBuffer();
        BufferedReader reader = null;
        try
        {
            streamReader = new InputStreamReader(stream);
            reader = new BufferedReader(streamReader);
            char[] buffer = new char[1024];
            int line = reader.read(buffer);

            while (line > 0)
            {
                fileBuffer.append(buffer, 0, line);
                line = reader.read(buffer);
            }
        }
        finally
        {
            if (streamReader != null)
            {
                try
                {
                    streamReader.close();
                }
                catch (Exception e)
                {
                    //Do nothing.
                }
            }
            if (reader != null)
            {
                try
                {
                    reader.close();
                }
                catch (Exception e)
                {
                    //Do nothing.
                }
            }
        }

        return fileBuffer;
    }

    /**
     * Reads a file into a string array
     * 
     * @param filename The file name
     * @return The file contents as a string array
     * @throws IOException 
     */
    public static String[] readFileAsArray(String filename) throws IOException
    {
        LinkedList<String> file = new LinkedList<String>();
        String[] lines = new String[0];
        String line;
        FileReader reader = null;
        LineNumberReader lineReader = null;

        try
        {
            reader = new FileReader(filename);
            lineReader = new LineNumberReader(reader);

            while ((line = lineReader.readLine()) != null)
            {
                file.add(line);
            }

            lines = new String[file.size()];
            lines = file.toArray(lines);
        }
        finally
        {
            try
            {
                lineReader.close();
                reader.close();
            }
            catch (Exception e)
            {
                // Do nothing
            }
        }

        return lines;
    }

    /**
     * Reads a file on workspace and returns an IDocument object with its content
     * 
     * @param file The file to read
     * @return The IDocument object containing the file contents
     * 
     * @throws CoreException
     */
    public static IDocument readFile(IFile file) throws CoreException
    {
        if (!canRead(file))
        {
            String errMsg = NLS.bind(UtilitiesNLS.EXC_FileUtil_TheFileCannotBeRead, file.getName());
            IStatus status = new Status(IStatus.ERROR, CommonPlugin.PLUGIN_ID, errMsg);

            throw new CoreException(status);
        }

        TextFileDocumentProvider documentProvider = new TextFileDocumentProvider();
        IDocument document = new Document();

        documentProvider.connect(file);
        document = documentProvider.getDocument(file);
        documentProvider.disconnect(file);

        return document;
    }

    /**
     * Saves the content of an IDocument object to a file on workspace
     * @param file The file
     * @param document The IDocument object
     * @param encoding The file encoding
     * @param overwrite If the file can be overwritten
     * @throws CoreException
     */
    public static void saveFile(IFile file, IDocument document, String encoding, boolean overwrite)
            throws CoreException
    {
        if (file.exists() && !overwrite)
        {
            String errMsg =
                    NLS.bind(UtilitiesNLS.EXC_FileUtil_CannotOverwriteTheFile, file.getName());
            IStatus status = new Status(IStatus.ERROR, CommonPlugin.PLUGIN_ID, errMsg);

            throw new CoreException(status);
        }

        if (!canWrite(file))
        {
            String errMsg = NLS.bind(UtilitiesNLS.EXC_FileUtil_ErrorWritingTheFile, file.getName());
            IStatus status = new Status(IStatus.ERROR, CommonPlugin.PLUGIN_ID, errMsg);

            throw new CoreException(status);
        }

        ByteArrayInputStream bais = null;

        try
        {
            bais = new ByteArrayInputStream(document.get().getBytes(encoding));
            file.setCharset(encoding, new NullProgressMonitor());
            file.setContents(bais, true, false, new NullProgressMonitor());
        }
        catch (UnsupportedEncodingException e1)
        {
            String errMsg =
                    NLS.bind(UtilitiesNLS.EXC_FileUtil_ErrorSettingTheFileEncoding, file.getName());
            IStatus status = new Status(IStatus.ERROR, CommonPlugin.PLUGIN_ID, errMsg);

            throw new CoreException(status);
        }
        finally
        {
            if (bais != null)
            {
                try
                {
                    bais.close();
                }
                catch (IOException e)
                {
                    // Do nothing.
                }
            }
        }
    }

    /**
     * Checks if a file can be read
     * 
     * @param file The file to be checked
     * @return true if the file can be read or false otherwise
     */
    public static boolean canRead(IFile file)
    {
        boolean canRead = true;
        InputStream is = null;

        try
        {
            if (file.exists())
            {
                file.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
                is = file.getContents();
                is.read();
            }
        }
        catch (CoreException e)
        {
            canRead = false;
        }
        catch (IOException e)
        {
            canRead = false;
        }
        finally
        {
            if (is != null)
            {
                try
                {
                    is.close();
                }
                catch (IOException e)
                {
                    // do nothing               
                }
            }
        }

        return canRead;
    }

    /**
     * Checks if a file can be written
     * 
     * @param file the file to be checked
     * @return true if the file can be written or false otherwise
     */
    public static boolean canWrite(IFile file)
    {
        boolean canWrite = true;

        if (file.exists() && canRead(file))
        {
            canWrite = !file.isReadOnly();
        }
        else
        {
            IFolder parent = (IFolder) file.getParent();

            if (!parent.isAccessible())
            {
                canWrite = false;
            }
            else
            {
                try
                {
                    if (parent.members() == null)
                    {
                        canWrite = false;
                    }
                    else
                    {
                        NullProgressMonitor nullProgressMonitor = new NullProgressMonitor();
                        file.create(null, true, nullProgressMonitor);
                        file.refreshLocal(IResource.DEPTH_ZERO, nullProgressMonitor);
                        file.delete(true, nullProgressMonitor);
                    }
                }
                catch (CoreException e)
                {
                    canWrite = false;
                }
            }
        }

        return canWrite;
    }

    /**
     * Checks if a File object can be read
     * 
     * @param file the File object
     * 
     * @return true if the File object can be read or false otherwise
     */
    public static boolean canRead(File file)
    {
        boolean canRead = false;

        if ((file != null) && file.exists())
        {
            FileInputStream fis = null;

            try
            {
                if (file.isFile())
                {
                    fis = new FileInputStream(file);
                    fis.read();
                    canRead = true;
                }
                else
                {
                    String[] children = file.list();

                    if (children != null)
                    {
                        canRead = true;
                    }
                }
            }
            catch (Exception e)
            {
                // Do nothing. canRead is false already
            }
            finally
            {
                try
                {
                    if (fis != null)
                    {
                        fis.close();
                    }
                }
                catch (IOException e)
                {
                    // Do nothing
                }
            }
        }

        return canRead;
    }

    /**
     * Checks if a File object can be written
     * 
     * @param file the File object
     * 
     * @return true if the File object can be written or false otherwise
     */
    public static boolean canWrite(File file)
    {
        boolean canWrite = false;

        if (file != null)
        {
            FileOutputStream fos = null;

            try
            {
                if (!file.exists())
                {
                    canWrite = file.createNewFile();

                    if (canWrite)
                    {
                        file.delete();
                    }
                }
                else if (file.isDirectory())
                {
                    File tempFile = File.createTempFile("StudioForAndroidFSChecking", null, file); //$NON-NLS-1$

                    if (tempFile.exists())
                    {
                        canWrite = true;
                        tempFile.delete();
                    }
                }
                else if (file.isFile())
                {
                    fos = new FileOutputStream(file);
                    fos.getFD();
                    canWrite = true;
                }
            }
            catch (Exception e)
            {
                // Do nothing. canWrite is false already
            }
            finally
            {
                if (fos != null)
                {
                    try
                    {
                        fos.close();
                    }
                    catch (IOException e)
                    {
                        // Do nothing
                    }
                }
            }
        }

        return canWrite;
    }

    /**
     * Unpack a zip file.
     * 
     * @param file the file
     * @param destination the destination path or null to unpack at the same directory of file
     * @return true if unpacked, false otherwise
     */
    public static boolean unpackZipFile(File file, String destination, IProgressMonitor monitor)
    {
        SubMonitor subMonitor = SubMonitor.convert(monitor);
        ZipFile zipFile = null;

        String extractDestination = destination != null ? destination : file.getParent();
        if (!extractDestination.endsWith(File.separator))
        {
            extractDestination += File.separator;
        }

        boolean unziped = true;
        try
        {
            zipFile = new ZipFile(file);
        }
        catch (Throwable e)
        {
            unziped = false;
            StudioLogger.error(FileUtil.class, "Error extracting file: " + file.getAbsolutePath() //$NON-NLS-1$
                    + " to " + extractDestination, e); //$NON-NLS-1$

        }
        if (zipFile != null)
        {
            Enumeration<? extends ZipEntry> entries = zipFile.entries();

            subMonitor.beginTask("Extracting files", Collections.list(entries).size()); //$NON-NLS-1$
            entries = zipFile.entries();
            InputStream input = null;
            OutputStream output = null;
            while (entries.hasMoreElements())
            {
                try
                {
                    ZipEntry entry = entries.nextElement();
                    File newFile = new File(extractDestination + entry.getName());
                    if (entry.isDirectory())
                    {
                        newFile.mkdirs();
                    }
                    else
                    {
                        newFile.getParentFile().mkdirs();
                        if (newFile.createNewFile())
                        {
                            input = zipFile.getInputStream(entry);
                            output = new BufferedOutputStream(new FileOutputStream(newFile));
                            copyStreams(input, output);
                        }
                    }
                }
                catch (Throwable t)
                {
                    unziped = false;
                    StudioLogger.error(FileUtil.class,
                            "Error extracting file: " + file.getAbsolutePath() + " to " //$NON-NLS-1$ //$NON-NLS-2$
                                    + extractDestination, t);
                }
                finally
                {
                    try
                    {
                        if (input != null)
                        {
                            input.close();
                        }
                        if (output != null)
                        {
                            output.close();
                        }
                    }
                    catch (Throwable t)
                    {
                        //do nothing
                    }
                    subMonitor.worked(1);
                }
            }
        }
        return unziped;
    }

    public static boolean extractZipArchive(File file, File destination,
            List<String> selectedEntries, IProgressMonitor monitor) throws IOException
    {
        SubMonitor subMonitor = SubMonitor.convert(monitor);
        ZipFile zipFile = null;
        CRC32 crc = new CRC32();
        byte[] buf = new byte[BUFFER_SIZE];

        File extractDestination = destination != null ? destination : file.getParentFile();

        if (!extractDestination.exists())
        {
            extractDestination.mkdirs();
        }

        boolean unziped = true;
        try
        {
            zipFile = new ZipFile(file);
        }
        catch (Throwable e)
        {
            unziped = false;
            StudioLogger.error(FileUtil.class, "Error extracting file: " + file.getAbsolutePath() //$NON-NLS-1$
                    + " to " + extractDestination, e); //$NON-NLS-1$

        }
        if (zipFile != null)
        {
            Enumeration<? extends ZipEntry> entries = zipFile.entries();

            subMonitor.beginTask("Extracting files", Collections.list(entries).size()); //$NON-NLS-1$
            entries = zipFile.entries();
            InputStream input = null;
            FileOutputStream output = null;
            int diagReturn = IDialogConstants.YES_ID;
            while (entries.hasMoreElements())
            {
                crc.reset();
                try
                {
                    ZipEntry entry = entries.nextElement();
                    if (selectedEntries.contains(entry.getName()))
                    {
                        File newFile = new File(extractDestination, entry.getName());
                        if ((diagReturn != IDialogConstants.YES_TO_ALL_ID) && newFile.exists())
                        {
                            diagReturn =
                                    EclipseUtils.showQuestionYesAllCancelDialog(
                                            UtilitiesNLS.FileUtil_File_Exists_Title, NLS.bind(
                                                    UtilitiesNLS.FileUtil_File_Exists_Message,
                                                    newFile.getAbsolutePath()));
                        }

                        if ((diagReturn == IDialogConstants.YES_ID)
                                || (diagReturn == IDialogConstants.YES_TO_ALL_ID))
                        {
                            newFile.delete();
                            if (entry.isDirectory())
                            {
                                newFile.mkdirs();
                            }
                            else
                            {
                                newFile.getParentFile().mkdirs();
                                if (newFile.createNewFile())
                                {
                                    input = zipFile.getInputStream(entry);
                                    output = new FileOutputStream(newFile);
                                    int length = 0;
                                    while ((length = input.read(buf, 0, BUFFER_SIZE)) > 1)
                                    {
                                        output.write(buf, 0, length);
                                        crc.update(buf, 0, length);
                                    }

                                    if (crc.getValue() != entry.getCrc())
                                    {
                                        throw new IOException();
                                    }

                                }
                            }
                        }
                        else
                        {
                            diagReturn = IDialogConstants.YES_ID; //Attempt to extract next entry
                        }
                    }
                }
                catch (IOException e)
                {
                    unziped = false;
                    StudioLogger.error(FileUtil.class,
                            "Error extracting file: " + file.getAbsolutePath() + " to " //$NON-NLS-1$ //$NON-NLS-2$
                                    + extractDestination, e);
                    throw e;
                }
                catch (Throwable t)
                {
                    unziped = false;
                    StudioLogger.error(FileUtil.class,
                            "Error extracting file: " + file.getAbsolutePath() + " to " //$NON-NLS-1$ //$NON-NLS-2$
                                    + extractDestination, t);
                }
                finally
                {
                    try
                    {
                        if (input != null)
                        {
                            input.close();
                        }
                        if (output != null)
                        {
                            output.close();
                        }
                    }
                    catch (Throwable t)
                    {
                        //do nothing
                    }
                    subMonitor.worked(1);
                }
            }
        }
        return unziped;

    }

    /**
     * Unpack a tar file.
     * 
     * @param file the file
     * @param destination the destination path or null to unpack at the same directory of file
     * @return true if unpacked, false otherwise
     */
    public static boolean unpackTarFile(File artifactFile, String destination)
    {
        boolean unpacked = true;

        String extractDestination = destination != null ? destination : artifactFile.getParent();
        if (!extractDestination.endsWith(File.separator))
        {
            extractDestination += File.separator;
        }

        List<String> commandList = new LinkedList<String>();
        commandList.add("tar"); //$NON-NLS-1$

        String fileName = artifactFile.getName();

        //tar.gz or tgz
        if (fileName.endsWith("gz")) //$NON-NLS-1$
        {
            commandList.add("xzf"); //$NON-NLS-1$
        }
        //tar.bz2
        else if (fileName.endsWith("bz2")) //$NON-NLS-1$
        {
            commandList.add("xjf"); //$NON-NLS-1$
        }
        //tar
        else if (fileName.endsWith("tar")) //$NON-NLS-1$
        {
            commandList.add("xf"); //$NON-NLS-1$
        }
        else
        {
            unpacked = false;
        }

        if (unpacked)
        {
            commandList.add(artifactFile.getAbsolutePath());
            File target = new File(extractDestination);
            if (target.exists() && target.isDirectory() && target.canWrite())
            {
                try
                {
                    Process p =
                            Runtime.getRuntime().exec(commandList.toArray(new String[0]), null,
                                    target);
                    try
                    {
                        p.waitFor();
                    }
                    catch (InterruptedException e)
                    {
                        //do nothing
                    }
                    if (p.exitValue() != 0)
                    {
                        unpacked = false;

                    }
                }
                catch (IOException e)
                {
                    unpacked = false;
                }
            }
        }

        return unpacked;
    }

    /**
     * Copy the input stream to the output stream
     * @param inputStream
     * @param outputStream
     * @throws IOException
     */
    public static void copyStreams(InputStream inputStream, OutputStream outputStream)
            throws IOException
    {
        byte[] buffer = new byte[1024];
        int length;

        while ((length = inputStream.read(buffer)) >= 0)
        {
            outputStream.write(buffer, 0, length);
        }
    }

    /**
     * Add a directory to a Project
     * @param project
     * @param parentFolder
     * @param folderName
     * @param monitor
     * @throws CoreException
     */
    public static void createProjectFolder(IProject project, String parentFolder,
            String folderName, IProgressMonitor monitor) throws CoreException
    {
        monitor.beginTask(UtilitiesNLS.UI_Project_Creating_Folder_Task, 100);

        try
        {
            monitor.setTaskName(UtilitiesNLS.UI_Project_Verifying_Folder_Task);
            if (folderName.length() > 0)
            {
                monitor.worked(10);
                IFolder folder = project.getFolder(parentFolder + folderName);
                monitor.worked(10);
                if (!folder.exists())
                {
                    monitor.worked(10);
                    if (FileUtil.canWrite(folder.getLocation().toFile()))
                    {
                        monitor.worked(10);
                        monitor.setTaskName(UtilitiesNLS.UI_Project_Creating_Folder_Task);
                        folder.create(true, true, new SubProgressMonitor(monitor, 60));
                    }
                    else
                    {
                        String errMsg =
                                NLS.bind(
                                        UtilitiesNLS.EXC_Project_CannotCreateFolderReadOnlyWorkspace,
                                        folder.getLocation().toFile().toString());
                        IStatus status = new Status(IStatus.ERROR, CommonPlugin.PLUGIN_ID, errMsg);
                        throw new CoreException(status);
                    }
                }
            }
        }
        finally
        {
            monitor.done();
        }
    }

    /**
     * Given a directory descriptor represented by a {@link File}, creates it
     * only if it does not exist. In case it does, try to create another
     * one with its name plus "-1". If it does exists, try to create it with
     * its name plus "+2", and so on... 
     * <br>
     * Note that the directory is not fisically created. To do so, on must
     * use the method {@link File#mkdir()}.
     * 
     * @param directory Directory to be created.
     * 
     * @return Returns the created directory as a {@link File}.
     */
    public static File createUniqueDirectoryDescriptor(File directory)
    {
        if (directory.exists())
        {
            boolean exists = true;
            int counter = 1;
            String rootPath = directory.getAbsolutePath();
            while (exists)
            {
                directory = new File(rootPath + "-" + counter); //$NON-NLS-1$
                exists = directory.exists();
                counter++;
            }
        }

        return directory;
    }

    /**
     * Return path with special characters escaped.
     * Special characters are system dependent, there is a set for linux and another for mac.
     * If {@code operationalSystem} is windows, the path is returned unchanged.
     * 
     * @param path to be escaped.
     * @param operatingSystem the target operation system that the path will be used. 
     * @return path with special characters escaped.
     * */
    public static String getEscapedPath(String path, String operatingSystem)
    {
        char[] specialCharSet = null;

        if (operatingSystem.equals(Platform.OS_LINUX))
        {
            specialCharSet = LINUX_SPECIAL_CHAR;
        }
        else if (operatingSystem.equals(Platform.OS_MACOSX))
        {
            specialCharSet = MAC_SPECIAL_CHAR;
        }

        if ((path != null) && (specialCharSet != null))
        {
            for (char c : specialCharSet)
            {
                CharSequence target = String.valueOf(c);
                CharSequence replacement = new String("\\" + String.valueOf(c)); //$NON-NLS-1$
                path = path.replace(target, replacement);
            }
        }

        return path;
    }

    /**
     * Return path with special characters escaped.
     * Special characters are system dependent, there is a set for linux and another for mac.
     * If the system is windows, returns the path unchanged.
     * 
     * @param path to be escaped
     * @return path with special characters escaped.
     * */
    public static String getEscapedPath(String path)
    {
        return getEscapedPath(path, Platform.getOS());
    }

    /**
     * Return path with special characters unescaped.
     * Special characters are system dependent, there is a set for linux and another for mac.
     * If the system is windows, returns the path unchanged.
     * 
     * @param path to be unescaped
     * @return path with special characters unescaped.
     * */
    public static String getUnescapedPath(String path)
    {
        char[] specialCharSet = null;

        if (Platform.getOS().equals(Platform.OS_LINUX))
        {
            specialCharSet = LINUX_SPECIAL_CHAR;
        }
        else if (Platform.getOS().equals(Platform.OS_MACOSX))
        {
            specialCharSet = MAC_SPECIAL_CHAR;
        }

        if ((path != null) && (specialCharSet != null))
        {
            for (char c : specialCharSet)
            {
                CharSequence target = new String("\\") + String.valueOf(c); //$NON-NLS-1$
                CharSequence replacement = String.valueOf(c);
                path = path.replace(target, replacement);
            }
        }

        return path;
    }

    public static String removeUnescapedQuotes(String path, String quoteReplacement)
    {
        //remove quotes and double quotes
        char quotes[] =
        {
                '\'', '"'
        };

        boolean escaped = false;

        for (int i = 0; i < path.length(); i++)
        {
            if (escaped == false)
            {
                if (path.charAt(i) == ESCAPE_CHAR)
                {
                    escaped = true;
                }
                else
                {
                    for (char quote : quotes)
                    {
                        if (path.charAt(i) == quote)
                        {
                            //split the string in two parts:
                            // - part1: before the quote
                            String part1 = path.substring(0, i);
                            // - part2: after the quote
                            String part2 = path.substring(i + 1, path.length());

                            //concatenate part1 and part2 with quoteReplacement in-between
                            //if quoteReplacement is the empty string (""), then part1 and part2 are juxtaposed
                            path = part1.concat(quoteReplacement).concat(part2);
                        }
                    }
                }
            }
            else
            {
                //current character is escaped, next character can't be escaped
                escaped = false;
            }
        }
        return path;
    }

    /**
     * Unescape characters and remove quotes and double quotes.
     * Special characters are system dependent, there is a set for linux and another for mac.
     * If the system is windows, returns the path unchanged.
     * 
     * @param path to be cleaned.
     * @param quoteReplacement string that will replace quotes and double quotes.
     * @return path without quotes, double quotes and special characters unescaped.
     * */
    public static String getCleanPath(String path, String quoteReplacement)
    {

        path = removeUnescapedQuotes(path, quoteReplacement);
        path = getUnescapedPath(path);

        return path;
    }

    public static String calculateMd5Sum(File file) throws IOException
    {
        String md5Sum = null;

        BigInteger hash = null;
        FileInputStream fis;
        fis = new FileInputStream(file);
        byte[] buf = new byte[1500000];

        try
        {
            MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); //$NON-NLS-1$
            int bytesRead = 0;
            while ((bytesRead = fis.read(buf)) > 0)
            {
                digest.update(buf, 0, bytesRead);
            }

            hash = new BigInteger(1, digest.digest());
            md5Sum = hash.toString(16);
        }
        catch (NoSuchAlgorithmException e)
        {
            // This exception should not happen, because we are using a valid
            // hard
            // coded value for the algorithm name. However, if it happens, log
            // it.
            warn("MOTODEV Studio could not find an instance of the MessageDigest for the MD5 algorithm"); //$NON-NLS-1$
            throw new IOException(UtilitiesNLS.FileUtil_Get_MD5_Algorithm_Failed);
        }
        finally
        {
            if (fis != null)
            {
                fis.close();
            }
        }

        if (md5Sum == null)
        {
            throw new IOException(NLS.bind(UtilitiesNLS.FileUtil_MD5_Calculation_Failed,
                    file.getAbsolutePath()));
        }

        return md5Sum;
    }

    /**
     * This method is responsible to copy informed source file to informed
     * target.
     * 
     * @param sourceFile
     * @param targetFile
     * @throws IOException
     */
    public static void copy(File sourceFile, File targetFile) throws IOException
    {
        OutputStream outputStream = new FileOutputStream(targetFile);
        InputStream inputStream = new FileInputStream(sourceFile);
        try
        {
            int length;
            byte[] buffer = new byte[FileUtil.BUFFER_SIZE];
            while ((length = inputStream.read(buffer)) >= 0)
            {
                outputStream.write(buffer, 0, length);
            }
        }
        catch (IOException e)
        {
            throw new IOException("Error copying file:" + sourceFile.getAbsolutePath() + //$NON-NLS-1$
                    " to " + targetFile.getAbsolutePath()); //$NON-NLS-1$
        }
        finally
        {
            outputStream.close();
            inputStream.close();
        }
    }

    /**
     * This method normalize a directory path.
     * 
     * @param folder Full path to a directory
     * @return The normalized path.
     */
    public static String normalizePath(String folder)
    {
        return folder.endsWith(File.separator) ? folder : folder + File.separator;
    }

    /**
     * Delete the specified file, recursively as necessary.
     * 
     * @param file The file to delete
     */
    public static void delete(File file)
    {
        if (file.exists())
        {
            if (file.isDirectory())
            {
                File[] files = file.listFiles();
                for (int i = 0; i < files.length; i++)
                {
                    delete(files[i]);
                }
            }
            file.delete();
        }
    }

    /**
     * Delete the specified file, recursively as necessary.
     * 
     * @param fileName The file to delete
     */
    public static void delete(String fileName)
    {
        delete(new File(fileName));
    }

    /**
     * This method creates the specified directory.
     * 
     * @param directory The directory to create.
     * @throws IOException
     */
    public static void mkdir(String directory) throws IOException
    {
        File f = new File(directory);
        if (f.exists())
        {
            if (f.isFile())
            {
                throw new IOException("Error creating directory:" + directory); //$NON-NLS-1$
            }
        }
        else
        {
            if (!f.mkdirs())
            {
                throw new IOException("Error creating directory:" + directory); //$NON-NLS-1$
            }
        }
    }

}
