/*******************************************************************************
 * Copyright (c) 2009, 2018 Cloudsmith Inc. and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Cloudsmith Inc. - initial API and implementation
 *     SAP AG - Ongoing development
 *******************************************************************************/

package org.eclipse.equinox.internal.p2.touchpoint.natives;

import static java.nio.file.FileVisitResult.CONTINUE;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static java.util.stream.Collectors.joining;
import static org.eclipse.equinox.internal.p2.touchpoint.natives.Util.logError;
import static org.eclipse.equinox.internal.p2.touchpoint.natives.Util.logWarning;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import org.eclipse.osgi.util.NLS;

/**
 * Stores files by moving them to a uniquely named temporary directory.
 * 
 * TheBackupStore remembers filenames and can recreate them in their original
 * location.
 *
 * <h3>Usage</h3> The user of this class should instantiate the BackupStore with
 * some prefix that is meaningful to a human. Uniqueness is obtained without the
 * prefix - the prefix is used to be able to differentiate between different
 * backup directories by a human (in case of crashes etc).
 *
 * If instantiated with a directory this directory will be used to store the
 * backup root directory. If this directory is null, the users home directory is
 * used by default.
 *
 * Once instantiated, use the {@link #backup(File)} and
 * {@link #backupDirectory(File)} methods to move files to backup instead of
 * deleting them. A file that is backed up should not be deleted - it is simply
 * moved out of the way. Use {@link #backupCopy(File)} to move the file out of
 * harms way, but keep a copy of it in the original location. The methods
 * {@link #backupAll(File)} and {@link #backupCopyAll(File)} backs up an entire
 * structure.
 *
 * When backup is finished - the user should either call {@link #restore()} to
 * put all of the files back, or call {@link #discard()} to remove all of the
 * backed up "copies".
 *
 * If {@link #restore()} or {@link #discard()} is not called the backup files
 * will never be deleted.
 *
 * The backup store does not synchronize directories - actions that write new
 * files are responsible for removing them. Overwriting existing files should be
 * done by first backing up the file, and then creating a new file. Modifying a
 * file, should be done by using {@link #backupCopy(File)} or first making a
 * copy, then backing up the original, and then renaming the copy.
 *
 * <h3>Read Only and Permissions</h3> Directories that are read only (to current
 * user) can not be backed up. Backup is performed using
 * {@link File#renameTo(File)} and handling of permissions is operating system
 * dependent. It is expected that a Un*x type system retains the permissions as
 * a file is moved to the backup store and later gets restored. Backup
 * directories are created as they are needed and will (at least on Un*x)
 * inherit the permissions from its parent directory.
 *
 * If a rename can not be performed, the backup store will make a copy and
 * delete the original file. This makes it possible to backup and restore across
 * volume boundaries.
 *
 * When restoring directories they will be created with permissions in a
 * platform specific way (on UN*IX they will inherit the permissions of the
 * parent directory).
 *
 * <h3>Checkpointing</h3> Checkpointing (i.e. to be able to rollback to a
 * particular point) can be implemented by using multiple instances of
 * BackupStore. The client code will need to remember the individual order among
 * the backup stores.
 *
 * <h3>Restartability</h3> Not implemented - it is possible to obtain the name
 * of the backup directories, so manual restore is possible after a crash. An
 * idea is to add persistence to a file, and be able to read it back in again.
 *
 * <h3>A note about exceptions</h3> In general {@link IllegalArgumentException}
 * is thrown when attempting an operation that is considered "wrong use", and an
 * {@link IllegalStateException} or subclass thereof is thrown on an overall
 * wrong use of BackupStore (i.e. attempt to backup when store has been
 * restored). Some cases of "wrong use" can not be differentiated from I/O
 * errors (like a "file not found" as this could be caused by an entire disk
 * disappearing - in these case an {@link IOException} is thrown.
 *
 * <h3>Implementation Note</h3> The backup root directory will contain folders
 * that reflects file system roots. These are encoded using "_" for the UNI*X
 * root directory, "__" for a Windows network mounted directory, and single
 * "drive letter" folders corresponding to Windows drive letters. Typically, on
 * UN*X there will only be a "_" directory in the backup root, and on windows
 * there will typically be a single directory called "C".
 */
public class SimpleBackupStore implements IBackupStore {
	public static final String BACKUP_FILE_EXTENSION = "p2bu"; //$NON-NLS-1$

	public static final String DIR_PLACEHOLDER = "emptydir"; //$NON-NLS-1$

	/**
	 * The name to use for a directory that represents leading separator (i.e. "/"
	 * or "\").
	 */
	private static final String ROOTCHAR = "_"; //$NON-NLS-1$

	/**
	 * Map of directory File to backup root (File) - the backup root has a directory
	 * named {@link #buStoreName} where the backup is found.
	 */
	private final Path buStoreRoot;

	private String buInPlaceSuffix;

	/**
	 * Backup files that sit next to the original rather than in the backup store.
	 */
	private List<Path> buInPlace;

	/**
	 * Counter of how many files where backed up. Used as a simple check mechanism
	 * if everything was restored (a guard against manual/external tampering with
	 * the backup directories).
	 */
	private long backupCounter;

	/**
	 * Counter of how many files where restored. See {@link #backupCounter}.
	 */
	private long restoreCounter;

	/**
	 * Flag indicating if this BackupStore has been restored or canceled.
	 */
	private boolean closed;

	/**
	 * Generates a BackupStore with a default prefix of ".p2bu" for backup directory
	 * and probe file.
	 */
	public SimpleBackupStore() {
		this(null, "." + BACKUP_FILE_EXTENSION); //$NON-NLS-1$
	}

	/**
	 * Generates a BackupStore with a specified prefix for backup directories and
	 * probe file.
	 *
	 * @param buStoreParent Parent under which the backup store will be created. If
	 *                      null, java.io.tmpdir is used
	 * @param prefix        Prefix used for human identification of backup stores.
	 */
	public SimpleBackupStore(File buStoreParent, String prefix) {
		String unique = UUID.randomUUID().toString();

		String buStoreName = prefix + "_" + unique; //$NON-NLS-1$
		this.buStoreRoot = (buStoreParent != null) ? buStoreParent.toPath().resolve(buStoreName)
				: Paths.get(System.getProperty("java.io.tmpdir")).resolve(buStoreName); //$NON-NLS-1$

		this.buInPlaceSuffix = String.format("-%s.%s", unique, BACKUP_FILE_EXTENSION); //$NON-NLS-1$
		this.buInPlace = new ArrayList<>();
	}

	/**
	 * Returns the unique backup name (this is the name of generated backup
	 * directories).
	 *
	 * @return the backup name.
	 */
	@Override
	public String getBackupName() {
		return buStoreRoot.getFileName().toString();
	}

	/**
	 * @return the parent dire under which backups are created
	 */
	public File getBackupRoot() {
		return buStoreRoot.toFile();
	}

	/**
	 * Backup the file by moving it to the backup store (for later (optional)
	 * restore). Calling this method with a file that represents a directory is
	 * equivalent to calling {@link #backupDirectory(File)}.
	 *
	 * A file (path) can only be backed up once per BackupStore instance. When the
	 * file is backed up, it is moved to a directory under this BackupStore
	 * instance's directory with a relative path corresponding to the original
	 * relative path from the backup root e.g. the file /A/B/C/foo.txt could be
	 * moved to /A/.p2bu_ffffff_ffffff/B/C/foo.txt when /A is the backup root.
	 *
	 * If a directory is first backed up, and later replaced by a regular file, and
	 * this file is backed up (or vice versa) - an {@link IllegalArgumentException}
	 * is thrown
	 *
	 * A backup can not be performed on a closed BackupStore.
	 *
	 * @param file - the file (or directory) to backup
	 * 
	 * @return true if the file was backed up, false if this file (path) has already
	 *         been backed up (the file is not moved to the store).
	 * 
	 * @throws IOException                - if the backup operation fails, or the
	 *                                    file does not exist
	 * @throws ClosedBackupStoreException - if the BackupStore has been closed
	 * @throws IllegalArgumentException   - on type mismatch (file vs. directory) of
	 *                                    earlier backup, or if file does not exist
	 */
	@Override
	public boolean backup(File file) throws IOException {
		assertOpen();

		Path path = file.toPath();

		if (Files.isDirectory(path)) {
			return backupDirectory(path.toFile());
		}

		if (!Files.exists(path)) {
			throw new IOException(NLS.bind(Messages.BackupStore_file_not_found, path.toAbsolutePath()));
		}

		Path buPath = toBackupPath(path);

		// Already backed up, but was a directory - wrong usage
		if (Files.isDirectory(buPath)) {
			throw new IllegalArgumentException(
					NLS.bind(Messages.BackupStore_directory_file_mismatch, buPath.toAbsolutePath()));
		}

		return moveToBackup(path, buPath);
	}

	/**
	 * Performs backup of an empty directory.
	 *
	 * The directory must be empty before it can be backed up (i.e. similar to a
	 * delete of a directory). The called must backup the files of the directory
	 * first. A call to backup a directory is really only needed for empty
	 * directories as a restore of a file will also restore all of its parent
	 * directories.
	 *
	 * @param file - the (empty) directory to back up
	 * 
	 * @return true if the directory was moved to backup. false if the directory was
	 *         already backed up.
	 *
	 * @throws IllegalArgumentException if file is not a directory, or is not empty.
	 * @throws IOException              if directory can not be moved to the backup
	 *                                  store, or if the directory is not writeable
	 */
	@Override
	public boolean backupDirectory(File file) throws IOException {
		assertOpen();

		Path path = file.toPath();

		if (!Files.isDirectory(path)) {
			throw new IllegalArgumentException(NLS.bind(Messages.BackupStore_not_a_directory, file.getAbsolutePath()));
		}

		if (Files.list(path).count() > 0) {
			throw new IllegalArgumentException(
					NLS.bind(Messages.BackupStore_directory_not_empty, file.getAbsolutePath()));
		}

		return moveDirToBackup(path);
	}

	/**
	 * Backs up a file, or everything under a directory.
	 *
	 * @param file - file to backup or directory
	 * 
	 * @throws IOException if backup operation failed
	 */
	@Override
	public void backupAll(File file) throws IOException {
		assertOpen();

		Path path = file.toPath().normalize();

		Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
			@Override
			public FileVisitResult visitFile(Path f, BasicFileAttributes attrs) throws IOException {
				backup(f.toFile());
				return CONTINUE;
			}

			@Override
			public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
				if (exc != null) {
					throw exc;
				}
				moveDirToBackup(dir);
				return CONTINUE;
			}
		});
	}

	/**
	 * Backup the file by leaving a copy of the contents in the original location.
	 * 
	 * Calling this method with a file that represents a directory throws an
	 * {@link IllegalArgumentException}.
	 *
	 * A file (path) can only be backed up once per BackupStore instance. When the
	 * file is backed up, it is moved to a directory under this BackupStore
	 * instance's directory with a relative path corresponding to the original
	 * relative path from the backup root e.g. the file /A/B/C/foo.txt could be
	 * moved to /A/.p2bu_ffffff_ffffff/B/C/foo.txt when /A is the backup root.
	 *
	 * If a directory is first backed up, and later replaced by a regular file, and
	 * this file is backed up (or vice versa) - an {@link IllegalArgumentException}
	 * is thrown
	 *
	 * A backup can not be performed on a closed BackupStore.
	 *
	 * @param file - the file (or directory) to backup
	 * 
	 * @return true if the file was backed up, false if this file (path) has already
	 *         been backed up (the file is not moved to the store).
	 * 
	 * @throws IOException                if the backup operation fails, or the file
	 *                                    does not exist
	 * @throws ClosedBackupStoreException if the BackupStore has been closed
	 * @throws IllegalArgumentException   on type mismatch (file vs. directory) of
	 *                                    earlier backup, or if file is a Directory
	 */
	@Override
	public boolean backupCopy(File file) throws IOException {
		assertOpen();

		Path path = file.toPath();

		if (!Files.exists(path)) {
			throw new IOException(NLS.bind(Messages.BackupStore_file_not_found, file.getAbsolutePath()));
		}

		if (Files.isDirectory(path)) {
			throw new IllegalArgumentException(
					NLS.bind(Messages.BackupStore_can_not_copy_directory, file.getAbsolutePath()));
		}

		Path buPath = toBackupPath(path);

		// Already backed up, but was a directory = wrong usage
		if (Files.isDirectory(buPath)) {
			throw new IllegalArgumentException(
					NLS.bind(Messages.BackupStore_directory_file_mismatch, buPath.toAbsolutePath()));
		}

		// Already backed up, can only be done once with one BackupStore
		if (Files.exists(buPath)) {
			return false;
		}

		Files.createDirectories(buPath.getParent());
		Files.copy(path, buPath, REPLACE_EXISTING);

		backupCounter++;
		return true;
	}

	/**
	 * Backs up a file, or everything under a directory.
	 * 
	 * A copy of the backup is left in the original place.
	 *
	 * @param file
	 * 
	 * @throws IOException
	 */
	@Override
	public void backupCopyAll(File file) throws IOException {
		assertOpen();

		Path path = file.toPath();
		if (!Files.exists(path)) {
			return;
		}

		path = path.normalize();

		if (Files.isRegularFile(path, LinkOption.NOFOLLOW_LINKS)) {
			backupCopy(file);
		} else if (Files.isDirectory(path)) {
			Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
				@Override
				public FileVisitResult visitFile(Path f, BasicFileAttributes attrs) throws IOException {
					backupCopy(f.toFile());
					return CONTINUE;
				}

				@Override
				public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
					if (exc != null) {
						throw exc;
					}
					copyDirToBackup(dir);
					return CONTINUE;
				}
			});
		}
	}

	/**
	 * Restores all backup files from backup store. Note that restore of a (non
	 * directory) file deletes an existing file or directory found in the restore
	 * location. When the backup has been restored this BackupStore instance is
	 * closed and can not be used for further backup or restore.
	 *
	 * If there are unrestorable items (non writable directories, or general IO
	 * exceptions) these items are written to the log, and the backup copies remain
	 * in the file system and can be manually restored (using a simple zip of the
	 * backup directory, and an unzip to the buRoot once the problem has been
	 * corrected).
	 *
	 * @throws IOException                if the backup was not fully restored -
	 *                                    unrestored items have been logged.
	 * @throws ClosedBackupStoreException if the backup is already closed.
	 */
	@Override
	public void restore() throws IOException {
		assertOpen();
		closed = true;

		// Put back all files.
		// Collect things that could not be restored
		Map<Path, Throwable> unrestorable = new HashMap<>();

		restoreBackups(unrestorable);
		restoreInPlaceBackups(unrestorable);

		boolean restored = true;

		// Checked failed attempts to restore
		if (!unrestorable.isEmpty()) {
			restored = false;

			unrestorable.forEach((p, err) -> {
				logError(NLS.bind(Messages.BackupStore_manual_restore_needed, err, p.toAbsolutePath()));
			});
		}

		// Check external tampering with backup store
		if (backupCounter != restoreCounter) {
			restored = false;

			if (!unrestorable.isEmpty()) {
				logError(NLS.bind(Messages.BackupStore_0_of_1_items_restored, restoreCounter, backupCounter));
			} else {
				logError(NLS.bind(Messages.BackupStore_externally_modified_0_of_1_restored, restoreCounter,
						backupCounter));
			}
		}

		if (!restored) {
			throw new IOException(Messages.BackupStore_errors_while_restoring_see_log);
		}
	}

	/**
	 * Discards and closes this BackupStore. Does nothing if this store is already
	 * restored or discarded.
	 */
	@Override
	public void discard() {
		if (closed) {
			return;
		}
		closed = true;

		try {
			deleteAll(buStoreRoot);
		} catch (IOException e) {
			logWarning(NLS.bind(Messages.BackupStore_can_not_remove_bu_directory, buStoreRoot.toAbsolutePath()));
		}

		for (Path buFile : buInPlace) {
			try {
				deleteAll(buFile);
			} catch (IOException e) {
				logWarning(NLS.bind(Messages.BackupStore_can_not_remove_bu_file, buFile.toAbsolutePath()));
			}
		}
	}

	private void assertOpen() {
		if (closed) {
			throw new ClosedBackupStoreException(Messages.BackupStore_closed_store);
		}
	}

	/**
	 * Makes sure a directory exists in the backup store without touching the original directory content
	 * 
	 * @param path
	 * 
	 * @return false if the directory is already created in the backup store, false if a placeholder had
	 *         to be created and backed up.
	 * 
	 * @throws IOException
	 */
	private boolean copyDirToBackup(Path path) throws IOException {
		Path buPath = toBackupPath(path);

		if (Files.exists(buPath)) {
			return false;
		}

		Path placeholderPath = path.resolve(DIR_PLACEHOLDER);
		try {
			Files.createFile(placeholderPath);
		} catch (IOException e) {
			throw new IOException(
					NLS.bind(Messages.BackupStore_can_not_create_placeholder, placeholderPath.toAbsolutePath()), e);
		}

		Path buPlaceholderPath = buPath.resolve(DIR_PLACEHOLDER);
		moveToBackup(placeholderPath, buPlaceholderPath);
		return true;
	}

	private boolean moveDirToBackup(Path dir) throws IOException {
		boolean copied = copyDirToBackup(dir);

		try {
			Files.delete(dir);
		} catch (IOException e) {
			throw new IOException(NLS.bind(Messages.BackupStore_can_not_remove, dir.toAbsolutePath()));
		}

		return copied;
	}

	/**
	 * Move/rename file to a backup file.
	 *
	 * Exposed for testing purposes.
	 *
	 * Callers of the method must have ensured that the source file exists and the
	 * backup file does not exist.
	 *
	 * @param file   source file to move; should already exist and must not be
	 *               directory
	 * @param buFile destination backup file to move to; should not exist and must
	 *               be a directory
	 *
	 * @throws IOException if the backup operation fails
	 */
	private boolean moveToBackup(Path path, Path buPath) throws IOException {
		// Already backed up. Can only be done once with one BackupStore.
		if (Files.exists(buPath)) {
			/*
			 * Although backed up, the file can be still on the file system. For example,
			 * two IUs may be unzipping their contents to the same location and share a few
			 * common files, which have to be removed twice.
			 */
			try {
				Files.delete(path);
			} catch (IOException e) {
				throw new IOException(NLS.bind(Messages.BackupStore_can_not_remove, path.toAbsolutePath()), e);
			}

			return false;
		}

		// make sure all of the directories exist / gets created
		Path buPathDir = buPath.getParent();
		try {
			Files.createDirectories(buPathDir);
		} catch (IOException e) {
			throw new IllegalArgumentException(
					NLS.bind(Messages.BackupStore_file_directory_mismatch, buPathDir.toAbsolutePath()), e);
		}

		try {
			move(path, buPath);
		} catch (IOException e) {
			// TODO Log exception?
			if (!isEclipseExe(path)) {
				throw e;
			}

			Path inPlaceBuPath = toInPlaceBackupPath(path);
			move(path, inPlaceBuPath);
			buInPlace.add(inPlaceBuPath);
		}

		backupCounter++;
		return true;
	}

	/**
	 * Restores everything stored in the backup root
	 *
	 * Responsible for converting the root prefix of the path from backup format
	 * back to the original real OS names. I.e. "_/" to "//", "__/" to "///", "C/"
	 * to "C:", etc.
	 *
	 * @param unrestorable accumulate unrestorable paths (including the entire
	 *                     backup store).
	 * 
	 * @throws IOException
	 */
	private void restoreBackups(Map<Path, Throwable> unrestorable) throws IOException {
		if (!Files.exists(buStoreRoot)) {
			unrestorable.put(buStoreRoot, new IOException(
					NLS.bind(Messages.BackupStore_missing_backup_directory, buStoreRoot.toAbsolutePath())));
			return;
		}

		Files.walkFileTree(buStoreRoot, new SimpleFileVisitor<Path>() {
			@Override
			public FileVisitResult preVisitDirectory(Path buDir, BasicFileAttributes attrs) {
				try {
					if (Files.isSameFile(buStoreRoot, buDir)) {
						return CONTINUE;
					}

					Path dir = toSourcePath(buDir);

					// There is a file where we the original directory used to be - delete it
					if (Files.isRegularFile(dir)) {
						Files.delete(dir);
					}

					// Make the original directory if needed
					Files.createDirectories(dir);
				} catch (IOException e) {
					unrestorable.put(buDir, e);
				}
				return CONTINUE;
			}

			@Override
			public FileVisitResult visitFile(Path buFile, BasicFileAttributes attrs) {
				Path file = toSourcePath(buFile);
				try {
					// The first level children of buStoreRoot are always directories since they
					// model file system roots
					if (Files.isSameFile(buFile.getParent(), buStoreRoot)) {
						unrestorable.put(buFile, new IOException("Not a directory")); //$NON-NLS-1$
					} else {
						/*
						 * Do not restore the place-holders as they are used to trigger creation of
						 * empty directories and are not wanted in the restored location.
						 * 
						 * They are counted as restored non the less.
						 */
						if (!DIR_PLACEHOLDER.equals(buFile.getFileName().toString())) {
							// Clean up the site where the original used to be.
							// It may be that a file or a directory now occupies it.
							deleteAll(file);

							// Move the backup to the original location
							move(buFile, file);
						} else {
							Files.delete(buFile);
						}

						restoreCounter++;
					}
				} catch (IOException e) {
					unrestorable.put(buFile, e);
				}
				return CONTINUE;
			}

			@Override
			public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
				unrestorable.put(file, exc);
				throw exc;
			}

			@Override
			public FileVisitResult postVisitDirectory(Path buDir, IOException exc) throws IOException {
				if (exc != null) {
					unrestorable.put(buDir, exc);
					throw exc;
				}
				try {
					Files.delete(buDir);
				} catch (DirectoryNotEmptyException e) {
					String children = Files.list(buDir)
							.map(p -> p.relativize(buDir))
							.map(Path::toString)
							.collect(joining(",")); //$NON-NLS-1$
					unrestorable.put(buDir, new IOException(String.format(
							"Directory %s not empty: %s", buDir, children, e))); //$NON-NLS-1$
				} catch (IOException e) {
					unrestorable.put(buDir, e);
				}
				return CONTINUE;
			}
		});
	}

	private void restoreInPlaceBackups(Map<Path, Throwable> unrestorable) {
		for (Path buPath : buInPlace) {
			Path path = toInPlaceSourcePath(buPath);

			try {
				move(buPath, path);
				restoreCounter++;
			} catch (IOException e) {
				unrestorable.put(buPath, e);
			}
		}
	}

	/**
	 * Converts a source path to a backup path.
	 * 
	 * Exposed for testing purposes.
	 *
	 * A leading "root" is transformed to the ROOTCHAR character. On Windows,
	 * network mapped drives starts with two separators - and are encoded as two
	 * ROOTCHAR.
	 *
	 * E.g. \\Host\C$\file becomes __\Host\C$\file /users/test/file becomes
	 * _/users/test/file C:/file becomes C/file
	 *
	 * @param file a source file that needs to be backed up
	 * 
	 * @return a file to which the original content can be backed up
	 * 
	 * @throws IOException
	 */
	protected Path toBackupPath(Path path) throws IOException {
		Path pathNormal = path.normalize();

		String buPath = pathNormal.toAbsolutePath().toString();

		String buPrefix = ""; //$NON-NLS-1$
		while (buPath.startsWith(File.separator)) {
			buPrefix += ROOTCHAR;
			buPath = buPath.substring(1);
		}

		// Linux or Windows net mount
		if (!buPrefix.isEmpty()) {
			buPath = Paths.get(buPrefix, buPath).toString();
		}
		// Windows
		else {
			// It is a windows drive letter first.
			// Transform C:/foo to C/foo
			int idx = buPath.indexOf(":"); //$NON-NLS-1$
			if (idx < 1) {
				throw new IllegalArgumentException("File is neither absolute nor has a drive name: " + buPath); //$NON-NLS-1$
			}
			buPath = buPath.substring(0, idx) + buPath.substring(idx + 1);
		}

		Path buFile = buStoreRoot.resolve(buPath);
		return buFile;
	}

	/**
	 * Converts a backup file to the original source file.
	 * 
	 * ///x/y/z -> ___x/y/z \\x\y\z c:\x\y\z -> c\x\y\z
	 * 
	 * @param buPath an absolute file under {@link #buStoreRoot} to which some
	 *               content is backed up.
	 * 
	 * @return the original source file to which the content can be restored.
	 */
	protected Path toSourcePath(Path buPath) {
		Path buPathRel = buStoreRoot.relativize(buPath);

		String pathName = buPathRel.toString();

		String prefix = ""; //$NON-NLS-1$
		while (pathName.startsWith(ROOTCHAR)) {
			prefix += File.separator;
			pathName = pathName.substring(1);
		}

		if (prefix.isEmpty()) {
			// The first char is a windows drive name
			pathName = pathName.charAt(0) + ":" + pathName.substring(1); //$NON-NLS-1$
		} else {
			pathName = prefix + pathName;
		}

		return Paths.get(pathName);
	}

	/**
	 * Converts a path to an in-place backup path.
	 * 
	 * Exposed for testing purposes.
	 * 
	 * @param path
	 * 
	 * @return a path next to the original where the original will be moved, rather
	 *         than will be moved
	 */
	protected Path toInPlaceBackupPath(Path path) {
		String buPathName = path.getFileName() + buInPlaceSuffix;
		Path buPath = path.toAbsolutePath().resolveSibling(buPathName);
		return buPath;
	}

	/**
	 * Converts a in-place backup path to the original source path.
	 * 
	 * Exposed for testing purposes.
	 * 
	 * @param path
	 * 
	 * @return a source path
	 */
	protected Path toInPlaceSourcePath(Path buPath) {
		String buPathName = buPath.getFileName().toString();

		int suffixIdx = buPathName.indexOf(buInPlaceSuffix);
		if (suffixIdx <= 0) {
			throw new IllegalArgumentException();
		}

		String pathName = buPathName.substring(0, suffixIdx);
		Path path = buPath.resolveSibling(pathName);
		return path;
	}

	/**
	 * A generic file operation that attempts to move a file.
	 *
	 * Exposed in a separate method for testing purposes.
	 */
	protected void move(Path source, Path target) throws IOException {
		Files.move(source, target, REPLACE_EXISTING);
	}

	private static boolean isEclipseExe(Path file) {
		String name = file.getFileName().toString();

		String launcher = System.getProperty("eclipse.launcher"); //$NON-NLS-1$
		if (launcher != null) {
			String launcherName = Paths.get(launcher).getFileName().toString();
			if (name.equalsIgnoreCase(launcherName)) {
				return true;
			}
		}

		return name.equalsIgnoreCase("eclipse.exe") || name.equalsIgnoreCase("eclipsec.exe"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Deletes a file, or a directory with all of it's children.
	 * 
	 * @param path
	 * 
	 * @throws IOException
	 */
	private static void deleteAll(Path path) throws IOException {
		if (!Files.exists(path)) {
			return;
		}

		Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
			@Override
			public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
				Files.delete(file);
				return CONTINUE;
			}

			@Override
			public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
				if (exc != null) {
					throw exc;
				}
				Files.delete(dir);
				return CONTINUE;
			}
		});
	}
}
