/*******************************************************************************
 * Copyright (c) 2000, 2015 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.core.tests.resources.regression;

import java.io.*;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.tests.resources.ResourceTest;

/**
 * A parent container (projects and folders) would become out-of-sync if any of
 * its children could not be deleted for some reason. These platform-
 * specific test cases ensure that it does not happen.
 */
public class Bug_026294 extends ResourceTest {

	public Bug_026294(String name) {
		super(name);
	}

	public static Test suite() {
		return new TestSuite(Bug_026294.class);
	}

	/**
	 * Tries to delete an open project containing an unremovable file.
	 * Works only for Windows.
	 */
	public void testDeleteOpenProjectWindows() {
		if (!(isWindows())) {
			return;
		}

		IProject project = null;
		InputStream input = null;
		File projectRoot = null;
		try {
			IWorkspace workspace = getWorkspace();
			project = workspace.getRoot().getProject(getUniqueString());
			IFolder folder = project.getFolder("a_folder");
			IFile file1 = folder.getFile("file1.txt");
			IFile file2 = project.getFile("file2.txt");
			IFile file3 = folder.getFile("file3.txt");
			IFile projectFile = project.getFile(new Path(".project"));

			ensureExistsInWorkspace(new IResource[] {file1, file2, file3}, true);
			projectRoot = project.getLocation().toFile();

			assertExistsInFileSystem("0.0", file1);
			assertExistsInFileSystem("0.1", file2);
			assertExistsInFileSystem("0.2", file3);
			assertExistsInFileSystem("0.3", folder);
			assertExistsInFileSystem("0.4", projectFile);

			// opens a file so it cannot be removed on Windows
			try {
				input = file1.getContents();
			} catch (CoreException ce) {
				ce.printStackTrace();
				fail("1.0");
			}
			assertTrue("1.2", projectFile.exists());
			assertTrue("1.3", projectFile.isSynchronized(IResource.DEPTH_INFINITE));

			try {
				project.delete(IResource.FORCE, getMonitor());
				fail("2.0 - should have failed");
			} catch (CoreException ce) {
				// success - a file couldn't be removed
			}

			// Delete is best-case so check all the files.
			// Do a check on disk and in the workspace in case something is out of sync.
			assertExistsInWorkspace("2.1.1", project);
			assertExistsInFileSystem("2.1.2", project);

			assertExistsInWorkspace("2.2.1", file1);
			assertExistsInFileSystem("2.2.2", file1);
			assertTrue("2.2.3", file1.isSynchronized(IResource.DEPTH_INFINITE));

			assertDoesNotExistInWorkspace("2.3.1", file2);
			assertDoesNotExistInFileSystem("2.3.2", file2);
			assertTrue("2.3.3", file2.isSynchronized(IResource.DEPTH_INFINITE));

			assertDoesNotExistInWorkspace("2.4.1", file3);
			assertDoesNotExistInFileSystem("2.4.2", file3);
			assertTrue("2.4.3", file3.isSynchronized(IResource.DEPTH_INFINITE));

			assertExistsInWorkspace("2.5.1", folder);
			assertExistsInFileSystem("2.5.2", folder);
			assertTrue("2.5.3", folder.isSynchronized(IResource.DEPTH_INFINITE));

			assertExistsInWorkspace("2.6.1", projectFile);
			assertExistsInFileSystem("2.6.2", projectFile);
			assertTrue("2.6.3", projectFile.isSynchronized(IResource.DEPTH_INFINITE));

			assertTrue("2.7.0", project.isSynchronized(IResource.DEPTH_ZERO));
			assertTrue("2.7.1", project.isSynchronized(IResource.DEPTH_INFINITE));

			assertClose(input);

			assertTrue("3.5", project.isSynchronized(IResource.DEPTH_INFINITE));
			try {
				project.delete(IResource.FORCE, getMonitor());
			} catch (CoreException e) {
				fail("4.0", e);
			}

			assertTrue("5.1", !project.exists());
			assertTrue("5.2", !file1.exists());
			assertTrue("5.3", file1.isSynchronized(IResource.DEPTH_INFINITE));
			assertTrue("5.4", project.isSynchronized(IResource.DEPTH_INFINITE));

			assertTrue("6.0", !projectRoot.exists());
		} finally {
			try {
				assertClose(input);
			} finally {
				if (projectRoot != null) {
					ensureDoesNotExistInFileSystem(projectRoot);
				}
			}
		}
	}

	/**
	 * Tries to delete an open project containing an irremovable file.
	 * Works only for Linux with natives.
	 */
	public void testDeleteOpenProjectLinux() {
		if (!(Platform.getOS().equals(Platform.OS_LINUX) && isReadOnlySupported())) {
			return;
		}

		IProject project = null;
		File projectRoot = null;
		IFolder folder = null;
		try {
			IWorkspace workspace = getWorkspace();
			project = workspace.getRoot().getProject(getUniqueString());
			folder = project.getFolder("a_folder");
			IFile file1 = folder.getFile("file1.txt");
			IFile file2 = project.getFile("file2.txt");

			ensureExistsInWorkspace(new IResource[] {file1, file2}, true);
			projectRoot = project.getLocation().toFile();

			// marks folder as read-only so its files cannot be deleted on Linux
			setReadOnly(folder, true);

			IFile projectFile = project.getFile(".project");
			assertTrue("1.2", projectFile.exists());
			assertTrue("1.3", projectFile.isSynchronized(IResource.DEPTH_INFINITE));

			try {
				project.delete(IResource.FORCE, getMonitor());
				fail("2.0 - should have failed");
			} catch (CoreException ce) {
				// success - a file couldn't be removed
			}
			assertTrue("2.1", project.exists());
			assertTrue("2.2", file1.exists());
			assertTrue("2.3", !file2.exists());
			assertTrue("2.5", folder.exists());
			assertTrue("2.6", projectFile.exists());
			assertTrue("2.7", project.isSynchronized(IResource.DEPTH_INFINITE));

			setReadOnly(folder, false);

			assertTrue("3.5", project.isSynchronized(IResource.DEPTH_INFINITE));
			try {
				project.delete(IResource.FORCE, getMonitor());
			} catch (CoreException ce) {
				ce.printStackTrace();
				fail("4.0", ce);
			}

			assertTrue("5.1", !project.exists());
			assertTrue("5.2", !file1.exists());
			assertTrue("5.3", file1.isSynchronized(IResource.DEPTH_INFINITE));
			assertTrue("5.4", project.isSynchronized(IResource.DEPTH_INFINITE));

			assertTrue("6.0", !projectRoot.exists());
		} finally {
			if (folder != null && folder.exists()) {
				setReadOnly(folder, false);
			}
			if (projectRoot != null) {
				ensureDoesNotExistInFileSystem(projectRoot);
			}
		}
	}

	/**
	 * Tries to delete a closed project containing an unremovable file.
	 * Works only for Windows.
	 */
	public void testDeleteClosedProjectWindows() {
		if (!isWindows()) {
			return;
		}

		IProject project = null;
		InputStream input = null;
		File projectRoot = null;
		IFile file1 = null;
		try {
			IWorkspace workspace = getWorkspace();
			project = workspace.getRoot().getProject(getUniqueString());
			IFolder folder = project.getFolder("a_folder");
			file1 = folder.getFile("file1.txt");
			IFile file2 = project.getFile("file2.txt");
			IFile file3 = folder.getFile("file3.txt");
			IFile projectFile = project.getFile(new Path(".project"));

			ensureExistsInWorkspace(new IResource[] {file1, file2, file3}, true);

			projectRoot = project.getLocation().toFile();

			// opens a file so it cannot be removed on Windows
			try {
				input = file1.getContents();
			} catch (CoreException ce) {
				ce.printStackTrace();
				fail("1.0");
			}

			try {
				project.close(getMonitor());
			} catch (CoreException e) {
				fail("1.1", e);
			}

			try {
				project.delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, getMonitor());
				fail("2.0 - should have failed");
			} catch (CoreException ce) {
				// success - a file couldn't be removed
			}
			assertTrue("2.1", project.exists());
			assertTrue("2.7", project.isSynchronized(IResource.DEPTH_INFINITE));
			assertExistsInFileSystem("2.8", projectFile);

			assertClose(input);
			assertTrue("3.5", project.isSynchronized(IResource.DEPTH_INFINITE));
			try {
				project.delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, getMonitor());
			} catch (CoreException ce) {
				ce.printStackTrace();
				fail("4.0", ce);
			}

			assertTrue("5.1", !project.exists());
			assertTrue("5.3", project.isSynchronized(IResource.DEPTH_INFINITE));
			assertTrue("6.0", !projectRoot.exists());
			assertDoesNotExistInFileSystem("7.0", projectFile);
		} finally {
			try {
				if (input != null) {
					input.close();
				}
			} catch (IOException e) {
				fail("8.0", e);
			} finally {
				if (projectRoot != null) {
					ensureDoesNotExistInFileSystem(projectRoot);
				}
			}
		}
	}

	/**
	 * Tries to delete a closed project containing an unremovable file.
	 * Works only for Linux with natives.
	 *
	 * TODO: enable this test once bug 48321 is fixed.
	 */
	public void testDeleteClosedProjectLinux() {
		if (!(Platform.getOS().equals(Platform.OS_LINUX))) {
			return;
		}

		IProject project = null;
		File projectRoot = null;
		IFolder folder = null;
		try {
			IWorkspace workspace = getWorkspace();
			project = workspace.getRoot().getProject(getUniqueString());
			folder = project.getFolder("a_folder");
			IFile file1 = folder.getFile("file1.txt");
			IFile file2 = project.getFile("file2.txt");
			IFile projectFile = project.getFile(new Path(".project"));

			ensureExistsInWorkspace(new IResource[] {file1, file2}, true);

			projectRoot = project.getLocation().toFile();

			// marks folder as read-only so its files cannot be removed on Linux
			setReadOnly(folder, true);

			try {
				project.close(getMonitor());
			} catch (CoreException e) {
				fail("1.0", e);
			}

			try {
				project.delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, getMonitor());
				fail("2.0 - should have failed");
			} catch (CoreException ce) {
				// success - a file couldn't be removed
			}

			assertTrue("3.0", project.exists());
			assertTrue("3.1", project.isSynchronized(IResource.DEPTH_INFINITE));
			assertExistsInFileSystem("3.2", projectFile);

			try {
				project.open(getMonitor());
			} catch (CoreException e) {
				fail("4.0", e);
			}

			setReadOnly(folder, false);
			try {
				project.delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, getMonitor());
			} catch (CoreException ce) {
				ce.printStackTrace();
				fail("5.0", ce);
			}

			assertTrue("6.0", !project.exists());
			assertTrue("6.1", project.isSynchronized(IResource.DEPTH_INFINITE));
			assertTrue("6.2", !projectRoot.exists());
			assertDoesNotExistInFileSystem("6.3", projectFile);
		} finally {
			if (folder != null && folder.exists()) {
				setReadOnly(folder, false);
			}
			if (projectRoot != null) {
				ensureDoesNotExistInFileSystem(projectRoot);
			}
		}
	}

	/**
	 * Tries to delete a folder containing an unremovable file.
	 * Works only for Windows.
	 */
	public void testDeleteFolderWindows() {
		if (!isWindows()) {
			return;
		}

		IProject project = null;
		InputStream input = null;
		File projectRoot = null;
		try {
			IWorkspace workspace = getWorkspace();
			project = workspace.getRoot().getProject(getUniqueString());
			IFolder folder = project.getFolder("a_folder");
			IFile file1 = folder.getFile("file1.txt");
			IFile file3 = folder.getFile("file3.txt");

			ensureExistsInWorkspace(new IResource[] {file1, file3}, true);
			projectRoot = project.getLocation().toFile();

			// opens a file so it cannot be removed on Windows
			try {
				input = file1.getContents();
			} catch (CoreException ce) {
				ce.printStackTrace();
				fail("1.0");
			}

			try {
				folder.delete(IResource.FORCE, getMonitor());
				fail("2.0 - should have failed");
			} catch (CoreException ce) {
				// success - a file couldn't be removed
			}
			assertTrue("2.2", file1.exists());
			assertTrue("2.4", !file3.exists());
			assertTrue("2.5", folder.exists());
			assertTrue("2.7", folder.isSynchronized(IResource.DEPTH_INFINITE));

			assertClose(input);

			assertTrue("3.5", project.isSynchronized(IResource.DEPTH_INFINITE));
			try {
				folder.delete(IResource.FORCE, getMonitor());
			} catch (CoreException ce) {
				ce.printStackTrace();
				fail("4.0", ce);
			}
			assertTrue("5.1", !file1.exists());
			assertTrue("5.2", !folder.exists());
			assertTrue("5.3", file1.isSynchronized(IResource.DEPTH_INFINITE));
			assertTrue("5.4", folder.isSynchronized(IResource.DEPTH_INFINITE));
		} finally {
			try {
				assertClose(input);
			} finally {
				if (projectRoot != null) {
					ensureDoesNotExistInFileSystem(projectRoot);
				}
			}
		}
	}

	/**
	 * Tries to delete a folder containing an irremovable file.
	 * Works only for Linux with natives.
	 */
	public void testDeleteFolderLinux() {
		if (!(Platform.getOS().equals(Platform.OS_LINUX))) {
			return;
		}

		IProject project = null;
		File projectRoot = null;
		IFolder subFolder = null;
		try {
			IWorkspace workspace = getWorkspace();
			project = workspace.getRoot().getProject(getUniqueString());
			IFolder folder = project.getFolder("a_folder");
			subFolder = folder.getFolder("sub-folder");
			IFile file1 = subFolder.getFile("file1.txt");
			IFile file3 = folder.getFile("file3.txt");

			ensureExistsInWorkspace(new IResource[] {file1, file3}, true);
			projectRoot = project.getLocation().toFile();

			// marks sub-folder as read-only so its files cannot be removed on Linux
			setReadOnly(subFolder, true);

			try {
				folder.delete(IResource.FORCE, getMonitor());
				fail("2.0 - should have failed");
			} catch (CoreException ce) {
				// success - a file couldn't be removed
			}
			assertTrue("2.2", file1.exists());
			assertTrue("2.3", subFolder.exists());
			assertTrue("2.4", !file3.exists());
			assertTrue("2.5", folder.exists());
			assertTrue("2.7", folder.isSynchronized(IResource.DEPTH_INFINITE));

			setReadOnly(subFolder, false);

			assertTrue("3.5", project.isSynchronized(IResource.DEPTH_INFINITE));
			try {
				folder.delete(IResource.FORCE, getMonitor());
			} catch (CoreException ce) {
				ce.printStackTrace();
				fail("4.0", ce);
			}
			assertTrue("5.1", !file1.exists());
			assertTrue("5.2", !subFolder.exists());
			assertTrue("5.3", !folder.exists());
			assertTrue("5.4", file1.isSynchronized(IResource.DEPTH_INFINITE));
			assertTrue("5.5", folder.isSynchronized(IResource.DEPTH_INFINITE));
		} finally {
			if (subFolder != null && subFolder.exists()) {
				setReadOnly(subFolder, false);
			}
			if (projectRoot != null) {
				ensureDoesNotExistInFileSystem(projectRoot);
			}
		}
	}

	/**
	 * @see org.eclipse.core.tests.harness.ResourceTest#tearDown()
	 */
	@Override
	protected void tearDown() throws Exception {
		super.tearDown();
	}
}
