package bndtools.refactor;

import java.io.InputStream;
import java.net.URI;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
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.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.resource.DeleteResourceChange;
import org.eclipse.ltk.core.refactoring.resource.ResourceChange;

public class CreateFileChange extends ResourceChange {

	private final IPath			path;
	private final InputStream	source;
	private final int			updateFlags;
	private final String		encoding;

	/**
	 * Construct a CreateFileChange object.
	 *
	 * @param path The path of the new file.
	 * @param source Provides the content of the new file.
	 * @param updateFlags Flags for creation (for possible values see
	 *            {@link IFile#create(InputStream, int, IProgressMonitor)}).
	 */
	public CreateFileChange(IPath path, InputStream source, int updateFlags, String encoding) {
		this.path = path;
		this.source = source;
		this.updateFlags = updateFlags;
		this.encoding = encoding;
	}

	@Override
	protected IResource getModifiedResource() {
		return ResourcesPlugin.getWorkspace()
			.getRoot()
			.getFile(path);
	}

	@Override
	public String getName() {
		return String.format("Create file %s", path.toString());
	}

	@Override
	public Change perform(IProgressMonitor monitor) throws CoreException {
		SubMonitor progress = SubMonitor.convert(monitor, encoding != null ? 2 : 1);

		IWorkspaceRoot root = ResourcesPlugin.getWorkspace()
			.getRoot();

		IFile file = root.getFile(path);
		file.create(source, updateFlags, progress.split(1, SubMonitor.SUPPRESS_NONE));

		if (encoding != null)
			file.setCharset(encoding, progress.split(1, SubMonitor.SUPPRESS_NONE));

		return new DeleteResourceChange(path, true);
	}

	@Override
	public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException {
		RefactoringStatus result = new RefactoringStatus();
		IFile file = ResourcesPlugin.getWorkspace()
			.getRoot()
			.getFile(path);

		URI location = file.getLocationURI();
		if (location == null) {
			result.addFatalError(String.format("The location for file %s is unknown", path));
			return result;
		}

		IFileInfo jFile = EFS.getStore(location)
			.fetchInfo();
		if (jFile.exists()) {
			result.addFatalError(String.format("File %s already exists", path));
			return result;
		}
		return result;
	}

}
