/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *     Sergey Prigogin (Google) - testWorkingLocationDeletion_bug433061
 *     Sergey Prigogin (Google) - [440283] Modify symlink tests to run on Windows with or without administrator privileges
 *******************************************************************************/
package org.eclipse.core.tests.resources;

import java.io.File;
import java.io.InputStream;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.internal.resources.Workspace;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;

/**
 * This class should be refactored into the black box tests for
 * solution, project, folder and file.
 */
public class WorkspaceTest extends ResourceTest {
	/**
	 * Need a zero argument constructor to satisfy the test harness.
	 * This constructor should not do any real work nor should it be
	 * called by user code.
	 */
	public WorkspaceTest() {
		super();
	}

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

	/**
	 * All of the WorkspaceTests build on each other. This test must
	 * be run last of all to clean up from all previous tests in this class.
	 * @throws Exception
	 */
	public void doCleanup() throws Exception {
		IPath location = getWorkspace().getRoot().getLocation().append("testProject");
		deleteOnTearDown(location);
		IPath location2 = getWorkspace().getRoot().getLocation().append("testProject2");
		deleteOnTearDown(location2);
		cleanup();
		assertTrue(location.toOSString() + " has not been deleted", !location.toFile().exists());
		assertTrue(location2.toOSString() + " has not been deleted", !location2.toFile().exists());
	}

	/**
	 * Returns a collection of string paths describing the standard
	 * resource hierarchy for this test.  In the string forms, folders are
	 * represented as having trailing separators ('/').  All other resources
	 * are files.  It is generally assumed that this hierarchy will be
	 * inserted under some solution and project structure.
	 */
	@Override
	public String[] defineHierarchy() {
		return new String[] {"/", "/1/", "/1/1", "/1/2", "/1/3", "/2/", "/2/1", "/2/2", "/2/3", "/3/", "/3/1", "/3/2", "/3/3", "/4/", "/5"};
	}

	protected IProject getTestProject() {
		return getWorkspace().getRoot().getProject("testProject");
	}

	protected IProject getTestProject2() {
		return getWorkspace().getRoot().getProject("testProject2");
	}

	public void setGetPersistentProperty(IResource target) throws Throwable {
		String value = "this is a test property value";
		QualifiedName name = new QualifiedName("itp-test", "testProperty");
		target.setPersistentProperty(name, value);
		// see if we can get the property
		assertTrue("get not equal set", target.getPersistentProperty(name).equals(value));
		// see what happens if we get a non-existant property
		name = new QualifiedName("itp-test", "testNonProperty");
		assertNull("non-existant persistent property not missing", target.getPersistentProperty(name));
	}

	public static Test suite() {
		TestSuite suite = new TestSuite(WorkspaceTest.class.getName());
		// test the basic create operations
		suite.addTest(new WorkspaceTest("testProjectCreation"));
		suite.addTest(new WorkspaceTest("testFolderCreation"));
		suite.addTest(new WorkspaceTest("testFileCreation"));
		suite.addTest(new WorkspaceTest("testFileInFolderCreation"));
		suite.addTest(new WorkspaceTest("testSetContents"));
		suite.addTest(new WorkspaceTest("testFileOverFolder"));
		suite.addTest(new WorkspaceTest("testFolderOverFile"));
		suite.addTest(new WorkspaceTest("testProjectCreateOpenCloseDelete"));
		suite.addTest(new WorkspaceTest("testProjectReferences"));

		// test closing and reopening
		suite.addTest(new WorkspaceTest("testProjectCloseOpen"));

		// test persistent properties on all the different resource types.
		suite.addTest(new WorkspaceTest("testSetGetProjectPersistentProperty"));
		suite.addTest(new WorkspaceTest("testSetGetFolderPersistentProperty"));
		suite.addTest(new WorkspaceTest("testSetGetFilePersistentProperty"));

		// test moves
		suite.addTest(new WorkspaceTest("testSimpleMove"));
		suite.addTest(new WorkspaceTest("testFileMove"));
		suite.addTest(new WorkspaceTest("testLeafFolderMove"));
		suite.addTest(new WorkspaceTest("testFolderMove"));

		// create a bunch of things at once
		suite.addTest(new WorkspaceTest("testMultiCreation"));

		// test deletions
		suite.addTest(new WorkspaceTest("testFolderDeletion"));
		suite.addTest(new WorkspaceTest("testFileDeletion"));
		suite.addTest(new WorkspaceTest("testFileEmptyDeletion"));
		suite.addTest(new WorkspaceTest("testMultiDeletion"));
		suite.addTest(new WorkspaceTest("testProjectDeletion"));
		suite.addTest(new WorkspaceTest("testWorkingLocationDeletion_bug433061"));

		suite.addTest(new WorkspaceTest("doCleanup"));
		return suite;
	}

	@Override
	protected void tearDown() throws Exception {
		// overwrite the superclass and do nothing since our test methods build on each other
	}

	public void testFileCreation() throws Throwable {
		IPath path = new Path("/testProject/testFile");
		IFile target = getWorkspace().getRoot().getFile(path);
		target.create(null, true, getMonitor());
		assertTrue(target.exists());
	}

	public void testFileDeletion() throws Throwable {
		IPath path = new Path("/testProject/testFileForDelete");
		IFile target = getWorkspace().getRoot().getFile(path);
		target.create(null, true, getMonitor());
		assertTrue(target.exists());
		target.delete(true, getMonitor());
		assertTrue(!target.exists());
	}

	public void testFileEmptyDeletion() throws Throwable {
		IPath path = new Path("/testProject/testFileForDelete2");
		IFile target = getWorkspace().getRoot().getFile(path);
		target.create(getContents(""), true, getMonitor());
		assertTrue(target.exists());
		target.delete(true, getMonitor());
		assertTrue(!target.exists());
	}

	public void testFileInFolderCreation() throws Throwable {
		IPath path = new Path("/testProject/testFolder/testFile2");
		IFile target = getWorkspace().getRoot().getFile(path);
		target.create(getRandomContents(), true, getMonitor());
		assertTrue(target.exists());
	}

	public void testFileMove() throws Throwable {
		IPath path = new Path("/testProject/targetFile");
		IFile target = getWorkspace().getRoot().getFile(path);
		target.create(getRandomContents(), true, getMonitor());
		IFile destination = getWorkspace().getRoot().getFile(new Path("/testProject/movedFile"));
		target.move(destination.getFullPath(), true, getMonitor());
		assertTrue(destination.exists());
		assertTrue(!target.exists());
	}

	public void testFileOverFolder() throws Throwable {
		IPath path = new Path("/testProject/testFolder");
		IFolder existing = getWorkspace().getRoot().getFolder(path);
		assertTrue(existing.exists());
		IFile target = getWorkspace().getRoot().getFile(path);
		try {
			target.create(null, true, getMonitor());
		} catch (CoreException e) {
			assertTrue(existing.exists());
			return;
		}
		fail("Should not be able to create file over folder");
	}

	public void testFolderCreation() throws Throwable {
		IPath path = new Path("/testProject/testFolder");
		IFolder target = getWorkspace().getRoot().getFolder(path);
		target.create(true, true, getMonitor());
		assertTrue(target.exists());
	}

	public void testFolderDeletion() throws Throwable {
		IProject project = getTestProject();
		IResource[] before = buildResources(project, new String[] {"c/", "c/b/", "c/x", "c/b/y", "c/b/z"});
		ensureExistsInWorkspace(before, true);
		//
		assertExistsInWorkspace(before);
		project.getFolder("c").delete(true, getMonitor());
		assertDoesNotExistInWorkspace(before);
	}

	public void testFolderMove() throws Throwable {
		IProject project = getTestProject();
		IResource[] before = buildResources(project, new String[] {"b/", "b/b/", "b/x", "b/b/y", "b/b/z"});
		IResource[] after = buildResources(project, new String[] {"a/", "a/b/", "a/x", "a/b/y", "a/b/z"});

		// create the resources and set some content in a file that will be moved.
		ensureExistsInWorkspace(before, true);
		String content = getRandomString();
		IFile file = project.getFile(new Path("b/b/z"));
		file.setContents(getContents(content), true, false, getMonitor());

		// Be sure the resources exist and then move them.
		assertExistsInWorkspace(before);
		project.getFolder("b").move(project.getFullPath().append("a"), true, getMonitor());

		//
		assertDoesNotExistInWorkspace(before);
		assertExistsInWorkspace(after);
		file = project.getFile(new Path("a/b/z"));
		assertTrue("get not equal set", compareContent(getContents(content), file.getContents(false)));
	}

	public void testFolderOverFile() throws Throwable {
		IPath path = new Path("/testProject/testFile");
		IFile existing = getWorkspace().getRoot().getFile(path);
		assertTrue(existing.exists());
		IFolder target = getWorkspace().getRoot().getFolder(path);
		try {
			target.create(true, true, getMonitor());
		} catch (CoreException e) {
			assertTrue(existing.exists());
			return;
		}
		fail("Should not be able to create folder over a file");
	}

	public void testLeafFolderMove() throws Throwable {
		IProject project = getTestProject();
		IFolder source = project.getFolder("testFolder");
		IFolder dest = project.getFolder("movedFolder");
		//
		source.move(dest.getFullPath(), true, getMonitor());
		assertExistsInWorkspace(dest);
		assertDoesNotExistInWorkspace(source);
	}

	public void testMultiCreation() throws Throwable {
		final IProject project = getWorkspace().getRoot().getProject("bar");
		final IResource[] resources = buildResources(project, new String[] {"a/", "a/b"});
		IWorkspaceRunnable body = monitor -> {
			if (!project.exists())
				project.create(null);
			if (!project.isOpen())
				project.open(null);
			// define an operation which will create a bunch of resources including a project.
			for (int i = 0; i < resources.length; i++) {
				IResource resource = resources[i];
				switch (resource.getType()) {
					case IResource.FILE :
						((IFile) resource).create(null, false, getMonitor());
						break;
					case IResource.FOLDER :
						((IFolder) resource).create(false, true, getMonitor());
						break;
					case IResource.PROJECT :
						((IProject) resource).create(getMonitor());
						break;
				}
			}
		};
		getWorkspace().run(body, getMonitor());
		assertExistsInWorkspace(project);
		assertExistsInWorkspace(resources);
	}

	public void testMultiDeletion() throws Throwable {
		IProject project = getTestProject();
		IResource[] before = buildResources(project, new String[] {"c/", "c/b/", "c/x", "c/b/y", "c/b/z"});
		ensureExistsInWorkspace(before, true);
		//
		assertExistsInWorkspace(before);
		getWorkspace().delete(before, true, getMonitor());
		assertDoesNotExistInWorkspace(before);
	}

	public void testProjectCloseOpen() throws Throwable {
		IProject target = getTestProject();
		target.close(getMonitor());
		assertTrue(target.exists());
		assertTrue(!target.isOpen());
		assertTrue(!target.getFolder("testFolder").exists());
		target.open(getMonitor());
		assertTrue(target.isOpen());
		assertTrue(target.getFolder("testFolder").exists());
	}

	public void testProjectCreateOpenCloseDelete() throws Throwable {
		IProject target = getTestProject2();
		target.create(null, getMonitor());
		assertTrue(target.exists());
		target.open(getMonitor());
		assertTrue(target.isOpen());
		target.close(getMonitor());
		assertTrue(!target.isOpen());
		target.delete(true, getMonitor());
		assertTrue(!target.exists());
	}

	public void testProjectCreation() throws Throwable {
		IProject target = getTestProject();
		target.create(null, getMonitor());
		assertTrue(target.exists());
		target.open(getMonitor());
		assertTrue(target.isOpen());
	}

	public void testProjectDeletion() throws Throwable {
		IProject target = getTestProject();
		target.delete(true, getMonitor());
		assertTrue("Project Deletion failed", !target.exists());
	}

	public void testWorkingLocationDeletion_bug433061() throws Throwable {
		// Only activate this test if testing of symbolic links is possible.
		if (!canCreateSymLinks())
			return;
		IProject project = getTestProject();
		project.create(null, getMonitor());
		IPath workingLocation = project.getWorkingLocation("org.eclipse.core.tests.resources");
		IPath linkTarget = getRandomLocation();
		try {
			linkTarget.toFile().mkdirs();
			File file = linkTarget.append("aFile").toFile();
			assertTrue(file.createNewFile());
			assertTrue(file.exists());
			// Create a symlink in the working location of the project pointing to linkTarget.
			createSymLink(workingLocation.toFile(), "link", linkTarget.toOSString(), true);
			project.delete(true, getMonitor());
			assertTrue("Project deletion failed", !project.exists());
			assertTrue("Working location was not deleted", !workingLocation.toFile().exists());
			assertTrue("File inside a symlinked directory got deleted", file.exists());
		} finally {
			Workspace.clear(linkTarget.toFile());
		}
	}

	public void testProjectReferences() throws Throwable {
		IProject target = getTestProject2();
		target.create(null, getMonitor());
		assertTrue(target.exists());
		IProject project = getTestProject();
		IProjectDescription description = project.getDescription();
		description.setReferencedProjects(new IProject[] {target});
		project.setDescription(description, getMonitor());
		assertTrue(target.getReferencingProjects().length == 1);

		target.delete(true, getMonitor());
		assertTrue(!target.exists());
	}

	public void testSetContents() throws Throwable {
		IPath path = new Path("/testProject/testFile");
		IFile target = getWorkspace().getRoot().getFile(path);
		String testString = getRandomString();
		target.setContents(getContents(testString), true, false, getMonitor());
		InputStream content = null;
		try {
			content = target.getContents(false);
			assertTrue("get not equal set", compareContent(content, getContents(testString)));
		} finally {
			content.close();
		}
	}

	public void testSetGetFilePersistentProperty() throws Throwable {
		IResource target = getWorkspace().getRoot().getFile(new Path("/testProject/testFile"));
		setGetPersistentProperty(target);
	}

	public void testSetGetFolderPersistentProperty() throws Throwable {
		IResource target = getWorkspace().getRoot().getFolder(new Path("/testProject/testFolder"));
		setGetPersistentProperty(target);
	}

	public void testSetGetProjectPersistentProperty() throws Throwable {
		IResource target = getWorkspace().getRoot().getProject("/testProject");
		setGetPersistentProperty(target);
	}

	public void testSetProperty() throws Throwable {
		IPath path = new Path("/testProject/testFile");
		IFile target = getWorkspace().getRoot().getFile(path);
		String value = "this is a test property value";
		QualifiedName name = new QualifiedName("itp-test", "testProperty");
		target.setPersistentProperty(name, value);
		assertTrue("get not equal set", target.getPersistentProperty(name).equals(value));
	}

	public void testSimpleMove() throws Throwable {
		IPath path = new Path("/testProject/simpleFile");
		IFile target = getWorkspace().getRoot().getFile(path);
		target.create(getRandomContents(), true, getMonitor());
		IFile destination = getWorkspace().getRoot().getFile(new Path("/testProject/newSimpleFile"));
		target.move(destination.getFullPath(), true, getMonitor());
		assertTrue(destination.exists());
		assertTrue(!target.exists());
	}
}
