/*******************************************************************************
 * Copyright (c) 2000, 2005 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.ui.internal.wizards.datatransfer;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.operation.ModalContext;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.IOverwriteQuery;


/**
 *	Operation for exporting the contents of a resource to the local file system.
 */
public class FileSystemExportOperation implements IRunnableWithProgress {
    private IPath path;

    private IProgressMonitor monitor;

    private FileSystemExporter exporter = new FileSystemExporter();

    private List resourcesToExport;

    private IOverwriteQuery overwriteCallback;

    private IResource resource;

    private List errorTable = new ArrayList(1);

    //The constants for the overwrite 3 state
    private static final int OVERWRITE_NOT_SET = 0;

    private static final int OVERWRITE_NONE = 1;

    private static final int OVERWRITE_ALL = 2;

    private int overwriteState = OVERWRITE_NOT_SET;

    private boolean createLeadupStructure = true;

    private boolean createContainerDirectories = true;

    /**
     *  Create an instance of this class.  Use this constructor if you wish to
     *  export specific resources without a common parent resource
     */
    public FileSystemExportOperation(List resources, String destinationPath,
            IOverwriteQuery overwriteImplementor) {
        super();

        // Eliminate redundancies in list of resources being exported
        Iterator elementsEnum = resources.iterator();
        while (elementsEnum.hasNext()) {
            IResource currentResource = (IResource) elementsEnum.next();
            if (isDescendent(resources, currentResource))
                elementsEnum.remove(); //Remove currentResource
        }

        resourcesToExport = resources;
        path = new Path(destinationPath);
        overwriteCallback = overwriteImplementor;
    }

    /**
     *  Create an instance of this class.  Use this constructor if you wish to
     *  recursively export a single resource
     */
    public FileSystemExportOperation(IResource res, String destinationPath,
            IOverwriteQuery overwriteImplementor) {
        super();
        resource = res;
        path = new Path(destinationPath);
        overwriteCallback = overwriteImplementor;
    }

    /**
     *  Create an instance of this class.  Use this constructor if you wish to
     *  export specific resources with a common parent resource (affects container
     *  directory creation)
     */
    public FileSystemExportOperation(IResource res, List resources,
            String destinationPath, IOverwriteQuery overwriteImplementor) {
        this(res, destinationPath, overwriteImplementor);
        resourcesToExport = resources;
    }

    /**
     * Add a new entry to the error table with the passed information
     */
    protected void addError(String message, Throwable e) {
        errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
                message, e));
    }

    /**
     *  Answer the total number of file resources that exist at or below self in the
     *  resources hierarchy.
     *
     *  @return int
     *  @param parentResource org.eclipse.core.resources.IResource
     */
    protected int countChildrenOf(IResource parentResource)
            throws CoreException {
        if (parentResource.getType() == IResource.FILE)
            return 1;

        int count = 0;
        if (parentResource.isAccessible()) {
            IResource[] children = ((IContainer) parentResource).members();
            for (int i = 0; i < children.length; i++)
                count += countChildrenOf(children[i]);
        }

        return count;
    }

    /**
     *	Answer a boolean indicating the number of file resources that were
     *	specified for export
     *
     *	@return int
     */
    protected int countSelectedResources() throws CoreException {
        int result = 0;
        Iterator resources = resourcesToExport.iterator();

        while (resources.hasNext())
            result += countChildrenOf((IResource) resources.next());

        return result;
    }

    /**
     *  Create the directories required for exporting the passed resource,
     *  based upon its container hierarchy
     *
     *  @param childResource org.eclipse.core.resources.IResource
     */
    protected void createLeadupDirectoriesFor(IResource childResource) {
        IPath resourcePath = childResource.getFullPath().removeLastSegments(1);

        for (int i = 0; i < resourcePath.segmentCount(); i++) {
            path = path.append(resourcePath.segment(i));
            exporter.createFolder(path);
        }
    }

    /**
     *	Recursively export the previously-specified resource
     */
    protected void exportAllResources() throws InterruptedException {
        if (resource.getType() == IResource.FILE)
            exportFile((IFile) resource, path);
        else {
            try {
                exportChildren(((IContainer) resource).members(), path);
            } catch (CoreException e) {
                // not safe to show a dialog
                // should never happen because the file system export wizard ensures that the
                // single resource chosen for export is both existent and accessible
                errorTable.add(e);
            }
        }
    }

    /**
     *	Export all of the resources contained in the passed collection
     *
     *	@param children java.util.Enumeration
     *	@param currentPath IPath
     */
    protected void exportChildren(IResource[] children, IPath currentPath)
            throws InterruptedException {
        for (int i = 0; i < children.length; i++) {
            IResource child = children[i];
            if (!child.isAccessible())
                continue;

            if (child.getType() == IResource.FILE)
                exportFile((IFile) child, currentPath);
            else {
                IPath destination = currentPath.append(child.getName());
                exporter.createFolder(destination);
                try {
                    exportChildren(((IContainer) child).members(), destination);
                } catch (CoreException e) {
                    // not safe to show a dialog
                    // should never happen because:
                    // i. this method is called recursively iterating over the result of #members,
                    //		which only answers existing children
                    // ii. there is an #isAccessible check done before #members is invoked
                    errorTable.add(e.getStatus());
                }
            }
        }
    }

    /**
     *  Export the passed file to the specified location
     *
     *  @param file org.eclipse.core.resources.IFile
     *  @param location org.eclipse.core.runtime.IPath
     */
    protected void exportFile(IFile file, IPath location)
            throws InterruptedException {
        IPath fullPath = location.append(file.getName());
        monitor.subTask(file.getFullPath().toString());
        String properPathString = fullPath.toOSString();
        File targetFile = new File(properPathString);

        if (targetFile.exists()) {
            if (!targetFile.canWrite()) {
                errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID,
                        0, NLS.bind(DataTransferMessages.DataTransfer_cannotOverwrite, targetFile.getAbsolutePath()),
                        null));
                monitor.worked(1);
                return;
            }

            if (overwriteState == OVERWRITE_NONE)
                return;

            if (overwriteState != OVERWRITE_ALL) {
                String overwriteAnswer = overwriteCallback
                        .queryOverwrite(properPathString);

                if (overwriteAnswer.equals(IOverwriteQuery.CANCEL))
                    throw new InterruptedException();

                if (overwriteAnswer.equals(IOverwriteQuery.NO)) {
                    monitor.worked(1);
                    return;
                }

                if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) {
                    monitor.worked(1);
                    overwriteState = OVERWRITE_NONE;
                    return;
                }

                if (overwriteAnswer.equals(IOverwriteQuery.ALL))
                    overwriteState = OVERWRITE_ALL;
            }
        }

        try {
            exporter.write(file, fullPath);
        } catch (IOException e) {
            errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
                    NLS.bind(DataTransferMessages.DataTransfer_errorExporting, fullPath, e.getMessage()), e));
        } catch (CoreException e) {
            errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
                    NLS.bind(DataTransferMessages.DataTransfer_errorExporting, fullPath, e.getMessage()), e));
        }

        monitor.worked(1);
        ModalContext.checkCanceled(monitor);
    }

    /**
     *	Export the resources contained in the previously-defined
     *	resourcesToExport collection
     */
    protected void exportSpecifiedResources() throws InterruptedException {
        Iterator resources = resourcesToExport.iterator();
        IPath initPath = (IPath) path.clone();

        while (resources.hasNext()) {
            IResource currentResource = (IResource) resources.next();
            if (!currentResource.isAccessible())
                continue;

            path = initPath;

            if (resource == null) {
                // No root resource specified and creation of containment directories
                // is required.  Create containers from depth 2 onwards (ie.- project's
                // child inclusive) for each resource being exported.
                if (createLeadupStructure)
                    createLeadupDirectoriesFor(currentResource);

            } else {
                // Root resource specified.  Must create containment directories
                // from this point onwards for each resource being exported
                IPath containersToCreate = currentResource.getFullPath()
                        .removeFirstSegments(
                                resource.getFullPath().segmentCount())
                        .removeLastSegments(1);

                for (int i = 0; i < containersToCreate.segmentCount(); i++) {
                    path = path.append(containersToCreate.segment(i));
                    exporter.createFolder(path);
                }
            }

            if (currentResource.getType() == IResource.FILE)
                exportFile((IFile) currentResource, path);
            else {
                if (createContainerDirectories) {
                    path = path.append(currentResource.getName());
                    exporter.createFolder(path);
                }

                try {
                    exportChildren(((IContainer) currentResource).members(),
                            path);
                } catch (CoreException e) {
                    // should never happen because #isAccessible is called before #members is invoked,
                    // which implicitly does an existence check
                    errorTable.add(e.getStatus());
                }
            }
        }
    }

    /**
     * Returns the status of the export operation.
     * If there were any errors, the result is a status object containing
     * individual status objects for each error.
     * If there were no errors, the result is a status object with error code <code>OK</code>.
     *
     * @return the status
     */
    public IStatus getStatus() {
        IStatus[] errors = new IStatus[errorTable.size()];
        errorTable.toArray(errors);
        return new MultiStatus(
                PlatformUI.PLUGIN_ID,
                IStatus.OK,
                errors,
                DataTransferMessages.FileSystemExportOperation_problemsExporting,
                null);
    }

    /**
     *  Answer a boolean indicating whether the passed child is a descendent
     *  of one or more members of the passed resources collection
     *
     *  @return boolean
     *  @param resources java.util.List
     *  @param child org.eclipse.core.resources.IResource
     */
    protected boolean isDescendent(List resources, IResource child) {
        if (child.getType() == IResource.PROJECT)
            return false;

        IResource parent = child.getParent();
        if (resources.contains(parent))
            return true;

        return isDescendent(resources, parent);
    }

    /**
     *	Export the resources that were previously specified for export
     *	(or if a single resource was specified then export it recursively)
     */
    public void run(IProgressMonitor progressMonitor)
            throws InterruptedException {
        this.monitor = progressMonitor;

        if (resource != null) {
            if (createLeadupStructure)
                createLeadupDirectoriesFor(resource);

            if (createContainerDirectories
                    && resource.getType() != IResource.FILE) {
                // ensure it's a container
                path = path.append(resource.getName());
                exporter.createFolder(path);
            }
        }

        try {
            int totalWork = IProgressMonitor.UNKNOWN;
            try {
                if (resourcesToExport == null)
                    totalWork = countChildrenOf(resource);
                else
                    totalWork = countSelectedResources();
            } catch (CoreException e) {
                // Should not happen
                errorTable.add(e.getStatus());
            }
            monitor.beginTask(DataTransferMessages.DataTransfer_exportingTitle, totalWork);
            if (resourcesToExport == null) {
                exportAllResources();
            } else {
                exportSpecifiedResources();
            }
        } finally {
            monitor.done();
        }
    }

    /**
     *	Set this boolean indicating whether a directory should be created for
     *	Folder resources that are explicitly passed for export
     *
     *	@param value boolean
     */
    public void setCreateContainerDirectories(boolean value) {
        createContainerDirectories = value;
    }

    /**
     *	Set this boolean indicating whether each exported resource's complete path should
     *	include containment hierarchies as dictated by its parents
     *
     *	@param value boolean
     */
    public void setCreateLeadupStructure(boolean value) {
        createLeadupStructure = value;
    }

    /**
     *	Set this boolean indicating whether exported resources should automatically
     *	overwrite existing files when a conflict occurs. If not
     *	query the user.
     *
     *	@param value boolean
     */
    public void setOverwriteFiles(boolean value) {
        if (value)
            overwriteState = OVERWRITE_ALL;
    }
}
