/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.common.internal.environment.eclipse;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Vector;
import org.eclipse.core.resources.IContainer;
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.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.environment.Choice;
import org.eclipse.wst.common.environment.StatusException;
import org.eclipse.wst.common.environment.IStatusHandler;



/**
* This class contains useful methods for working with Eclipse resources.
*/
public final class FileResourceUtils
{
  //
  // Keeps the IWorkspace hanging around. See getWorkspace().
  //
  private static IWorkspace workspace_ = null;
  //
  // Keeps the IWorkspaceRoot hanging around. See getWorkspaceRoot().
  //
  private static IWorkspaceRoot root_ = null;

 /**
  * Returns the IWorkspaceRoot object.
  * @return The IWorkspaceRoot object.
  */
  public static IWorkspaceRoot getWorkspaceRoot ()
  {
    if (root_ == null)
    {
      root_ = ResourcesPlugin.getWorkspace().getRoot();
    }
    return root_;
  }

 /**
  * Returns the IWorkspace object.
  * @return The IWorkspace object.
  */
  public static IWorkspace getWorkspace ()
  {
    if (workspace_ == null)
    {
      if (root_ == null)
      {
        root_ = ResourcesPlugin.getWorkspace().getRoot();
      }
      
      workspace_ = root_.getWorkspace();
    }
    
    return workspace_;
  }
  
  /**
   * 
   * @return returns an array of three common choices. (ie. Yes, yes all, and cancel )
   */
  public static Choice[] getThreeStateFileOptions() 
  {
    Vector choices = new Vector();
    
    choices.add(new Choice( 'Y', Messages.LABEL_YES ));
    choices.add(new Choice( 'A', Messages.LABEL_YES_TO_ALL ));
    choices.add(new Choice( 'C', Messages.LABEL_CANCEL ));
    
    return (Choice[])choices.toArray(new Choice[choices.size()]);
  }
  
  /**
  * Returns an
  * {@link org.eclipse.core.resources.IResource IResource}
  * of the given absolute pathname or null if no such resource exists.
  * @param absolutePathname The absolute path of the resource.
  * @return The <code>IResource</code>.
  */
  public static IResource findResource ( String absolutePathname )
  {
    if (absolutePathname == null)
    {
      return null;
    }
    
    return findResource(new Path(absolutePathname));
  }

  /**
  * Returns an
  * {@link org.eclipse.core.resources.IResource IResource}
  * of the given absolute path or null if no such resource exists.
  * @param absolutePath The absolute <code>IPath</code> of the resource.
  * @return The <code>IResource</code>.
  */
  public static IResource findResource ( IPath absolutePath )
  {
    if (absolutePath == null)
    {
      return null;
    }
    
    return FileResourceUtils.getWorkspaceRoot().findMember(absolutePath);
  }
  
  /**
   * Copies a file from a plugin's installation location
   * to an Eclipse folder.
   * @param plugin The plugin containing the files to copy.
   * Must not be null.
   * @param sourcePath The path, relative to the <code>plugin</code>
   * install location, containing the files to copy.
   * If null, then the plugin install location is the source path
   * (ie. null is equivalent to ".").
   * @param pathname The pathname of the file to copy.
   * The pathname is relative to the <code>plugin sourcePath</code>.
   * Must not be null.
   * @param targetPath The absolute Eclipse path of the folder to
   * which the file will be copied. The relative pathname of the
   * file is preserved.
   * Must not be null.
   * @param createFolders The intermediate folder creation policy, one of
   * {@link #CREATE CREATE} or {@link #DONT_CREATE DONT_CREATE}.
   * <ul>
   * <li><code>CREATE</code> -
   * If any intermediate folders in the given <code>absolutePath</code>
   * do not exist, they will be created.
   * <li><code>DONT_CREATE</code> -
   * If any intermediate folders in the given <code>absolutePath</code>
   * do not exist, the method will throw a <code>CoreException</code>.
   * </ul>
   * @param overwriteFile The policy for existing files, one of
   * {@link #OVERWRITE OVERWRITE} or {@link #DONT_OVERWRITE DONT_OVERWRITE}.
   * <ul>
   * <li><code>OVERWRITE</code> -
   * If a resource of the same name as the given
   * <code>absolutePath</code> already exists and is a file,
   * it will be replaced.
   * If the resource already exists and it is not a file,
   * then no file will be created and
   * a <code>CoreException</code> will be thrown.
   * <li><code>DONT_OVERWRITE</code> -
   * If any resource of the same name as the given
   * <code>absolutePath</code> already exists,
   * then no file will be created and
   * a <code>CoreException</code> will be thrown.
   * </ul>
   * @param progressMonitor The progress monitor for the operation, or null.
   * @throws CoreException An exception containing an
   * {@link org.eclipse.core.runtime.IStatus IStatus}
   * with a severity of <code>IStatus.ERROR</code> and a
   * locale-specific description of the cause.
   */
   static public void copyFile( Plugin plugin,
                                IPath sourcePath,
                                IPath pathname,
                                IPath targetPath,
                                IStatusHandler statusMonitor )
     throws CoreException
   {
     try
     {
       IPath target = targetPath.append(pathname);
       IPath source = sourcePath == null ? pathname : sourcePath.append(pathname);
       InputStream input = plugin.openStream(source);
       createFile(target, input, statusMonitor);
     }
     catch (IOException e)
     {
       throw new CoreException(new Status(IStatus.ERROR,
                               plugin.getBundle().getSymbolicName(),
                               0,
                               Messages.MSG_ERROR_IO,e));
     }
   }
   
  /**
   * Deletes a file under a container.
   * The container must already exist.
   * @param file - the IFile to be deleted
   * @param progressMonitor
   * @param statusMonitor
   * @return True if the file does not exist or if it exists and is successfully deleted. False otherwise.
   */
  public static boolean deleteFile( IFile file,
                                    IStatusHandler statusMonitor)
    throws CoreException
  {
    if (file.exists())
    {      
      //We have permission to overwrite so check if file is read-only
      if (file.isReadOnly())
      {        
        IFile[] files = new IFile[1];
        files[0] = file;
        IStatus status = getWorkspace().validateEdit(files, null);
        
        if( status.getSeverity() == IStatus.ERROR )
        {
          statusMonitor.reportError( status );
          return false;
        }
      }
      
      file.delete(true, null);
    }
    //At this point, either the file did not exist or we successfully deleted
    // it. Return success.
    return true;
  }

  /**
   * Deletes a folder under a container.
   * @param folder - the IFolder to be deleted
   * @param progressMonitor
   * @param statusMonitor
   * @return True if the folder does not exist or if it exists and is successfully deleted along with its members. False otherwise.
   */
   public static boolean deleteFolder( IFolder folder,
                                       IStatusHandler statusMonitor )
     throws CoreException
   {
     if (!folder.exists()) return true;

     boolean     deleted   = true;
     IResource[] resources = folder.members();
     
     for (int i=0; i<resources.length; i++)
     {
       IResource resource = resources[i];
       if (resource instanceof IFile)
       {
         deleted = deleteFile((IFile)resource, statusMonitor);
       }
       if (resource instanceof IFolder)
       {
         deleted = deleteFolder( (IFolder)resource, statusMonitor);
       }

       if( !deleted ) break;
     }
     
     if( deleted )
     {
       folder.delete(true, true, null);
       return true;
     }
     else
       return false;
   }

  /**
  * Creates a file of the given <code>absolutePath</code>
  * and returns its handle as an <code>IFile</code>.
  * If the file cannot be created, a
  * <code>CoreException</code> containing an
  * <code>IStatus</code> object is thrown.
  * @param absolutePath The absolute path of the file to create.
  * The project at the beginning of the path must already exist,
  * that is, this method cannot be used to create projects.
  * @param progressMonitor The progress monitor for the operation, or null.
  * @return The {@link org.eclipse.core.resources.IFile IFile}
  * handle of the file.
  * @throws CoreException An exception containing an
  * {@link org.eclipse.core.runtime.IStatus IStatus}
  * with a severity of <code>IStatus.ERROR</code> and a
  * locale-specific description of the cause.
  */
  public static IFile createFile (
    IPath           absolutePath,
    InputStream     inputStream,
    IStatusHandler   statusHandler )

    throws CoreException 
  {    
    if (!absolutePath.isAbsolute())
    {
      throw new CoreException(new Status(IStatus.ERROR, "ResourceUtils",0, NLS.bind( Messages.MSG_ERROR_PATH_NOT_ABSOLUTE, absolutePath.toString() ),null));
    }
    if (absolutePath.segmentCount() < 1)
    {
      throw new CoreException(new Status(IStatus.ERROR,"ResourceUtils",0,NLS.bind( Messages.MSG_ERROR_PATH_EMPTY, absolutePath.toString() ),null));
    }
    if (absolutePath.segmentCount() < 2)
    {
      throw new CoreException(new Status(IStatus.ERROR,"ResourceUtils",0,NLS.bind( Messages.MSG_ERROR_PATH_NOT_FOLDER, absolutePath.toString() ),null));
    }
    IContainer parent   = makeFolderPath(absolutePath.removeLastSegments(1), statusHandler);
    String     fileName = absolutePath.lastSegment();
    
    return makeFile(parent, fileName, inputStream, statusHandler);
  }

  /**
  * Creates under the given <code>project</code>
  * a file of the given <code>relativePath</code>
  * and returns its handle as an <code>IFile</code>.
  * If the file cannot be created, a
  * <code>CoreException</code> containing an
  * <code>IStatus</code> object is thrown.
  * @param absolutePath The absolute path of the file to create.
  * The project at the beginning of the path must already exist,
  * that is, this method cannot be used to create projects.
  * @param createFolders The intermediate folder creation policy, one of
  * {@link #CREATE CREATE} or {@link #DONT_CREATE DONT_CREATE}.
  * <ul>
  * <li><code>CREATE</code> -
  * If any intermediate folders in the given <code>absolutePath</code>
  * do not exist, they will be created.
  * <li><code>DONT_CREATE</code> -
  * If any intermediate folders in the given <code>absolutePath</code>
  * do not exist, the method will throw a <code>CoreException</code>.
  * </ul>
  * @param overwriteFile The policy for existing files, one of
  * {@link #OVERWRITE OVERWRITE} or {@link #DONT_OVERWRITE DONT_OVERWRITE}.
  * <ul>
  * <li><code>OVERWRITE</code> -
  * If a resource of the same name as the given
  * <code>absolutePath</code> already exists and is a file,
  * it will be replaced.
  * If the resource already exists and it is not a file,
  * then no file will be created and
  * a <code>CoreException</code> will be thrown.
  * <li><code>DONT_OVERWRITE</code> -
  * If any resource of the same name as the given
  * <code>absolutePath</code> already exists,
  * then no file will be created and
  * a <code>CoreException</code> will be thrown.
  * </ul>
  * @param progressMonitor The progress monitor for the operation, or null.
  * @return The {@link org.eclipse.core.resources.IFile IFile}
  * handle of the file.
  * @throws CoreException An exception containing an
  * {@link org.eclipse.core.runtime.IStatus IStatus}
  * with a severity of <code>IStatus.ERROR</code> and a
  * locale-specific description of the cause.
  */
  public static IFile createFile (
    IProject        project,
    IPath           relativePath,
    InputStream     inputStream,
    IStatusHandler   statusMonitor )
 
    throws CoreException 
  {
    IPath absolutePath = project.getFullPath().append(relativePath);
    return createFile(absolutePath, inputStream, statusMonitor);
  }

  /**
  * Creates an output stream that can be used to write to the
  * given <code>file</code>. Actual changes to the workspace
  * may occur during creation of the stream, while writing to
  * the stream, or when the stream is closed.
  * A <code>CoreException</code> containing
  * an <code>IStatus</code> will be thrown
  * at some point in the lifecycle of the stream
  * if the file resource cannot be created.
  * @param file The {@link org.eclipse.core.resources.IFile IFile}
  * handle of the file resource to create. The project implied by the
  * pathname of the file must already exist,
  * that is, this method cannot be used to create projects.
  * @param progressMonitor The progress monitor for the operation, or null.
  * @return An <code>OutputStream</code> tied to the file resource.
  * Actual checks of or changes to the workspace may occur as early during
  * stream creation, closure, or any time in between.
  * @throws CoreException An exception containing an
  * {@link org.eclipse.core.runtime.IStatus IStatus}
  * with a severity of <code>IStatus.ERROR</code> and a
  * locale-specific description of the cause.
  * Reasons include:
  * <ol>
  * <li>The project of the given file's path does not exist.
  * <li>A non-file resource of the same name of the given file
  * already exists.
  * <li>A file resource of the same name of the given file
  * already exists, and <code>overwriteFile</code> is false.
  * <li>One or more intermediate folders to the given file
  * do not exist, and <code>createFolders</code> is false.
  * </ol>
  */

  public static OutputStream newFileOutputStream (
       IPath            file,
       IStatusHandler    statusHandler )
 
  {
    return new FileResourceOutputStream(file, statusHandler);
  }

  //----------------------------------------------------------------------
  // Naughty bits...
  //----------------------------------------------------------------------

  //
  // Creates a path of folders.
  // Do not call with an absolutePath of less than one segment.
  //
  /**
   * Creates a path of folders.
   * Do not call with an absolutePath of less than one segment.
   * @param resourceContext the resource context for making folders.
   * @param absolutePath the path of folders that will be created.
   * @param progressMonitor the progress monitor to be used.
   * @param statusHandler the status handler.
   * @return returns the IContainer of the created folder.
   */
  public static IContainer makeFolderPath (
    IPath            absolutePath,
    IStatusHandler    statusHandler )
  
    throws CoreException
  {
    if (absolutePath.segmentCount() <= 1)
    {
      return getWorkspaceRoot().getProject(absolutePath.segment(0));
    }
    else
    {
      IContainer parent = makeFolderPath(absolutePath.removeLastSegments(1), statusHandler );
      String folderName = absolutePath.lastSegment();
      
      return makeFolder(parent,folderName, statusHandler );
    }
  }
  //
  // Creates a folder under a container.
  // The container must already exist.
  //
 private static IFolder makeFolder (
    IContainer       parent,
    String           folderName,
    IStatusHandler    statusHandler )
  
  throws CoreException
  {
    IResource child  = parent.findMember(folderName);
    
    if( child == null )
    {      
      IFolder folder = parent.getFolder(new Path(folderName));
      folder.create(true,true,null);
      return folder;
    }
    else if( child.getType() == IResource.FOLDER )
    {
      return (IFolder)child;
    }
    else
    {
      throw new CoreException(
        new Status( IStatus.ERROR, 
                    "ResourceUtils",
                    0, 
					NLS.bind( Messages.MSG_ERROR_RESOURCE_NOT_FOLDER, parent.getFullPath().append(folderName).toString()),
			null ) );
    }
  }

  //
  // Creates a file under a container.
  // The container must already exist.
  //
 private static IFile makeFile (
    IContainer       parent,
    String           fileName,
    InputStream      inputStream,
    IStatusHandler    statusHandler )
 
    throws CoreException
  {
    IResource child  = parent.findMember(fileName);
    
    if( child != null )
    {
      if( child.getType() == IResource.FILE )
      {        
        //We have permission to overwrite so check if file is read-only
        if( child.getResourceAttributes().isReadOnly() )
        {
          IFile[] files = new IFile[1];
          files[0] = (IFile)child;
          
          IStatus status = getWorkspace().validateEdit(files,null);
          
          try
          {
            statusHandler.report( status );
          }
          catch( StatusException exc )
          {
            return null;
          }
        }

        //Change the contents of the existing file.
        IFile file = parent.getFile( new Path(fileName) );
        file.setContents( inputStream, true, true, null );
        
        return file;
      
      }
      else
      {
        throw new CoreException( 
          new Status( IStatus.ERROR,
                      "ResourceUtils",
                      0, 
				      NLS.bind( Messages.MSG_ERROR_RESOURCE_NOT_FILE, parent.getFullPath().append(fileName)),
					  null ) );
      }
    }
    else
    {
      //Create a new file.
      IFile file = parent.getFile( new Path(fileName) );
      file.create( inputStream, true, null);
      
      return file;
    }
  }
}
