/*******************************************************************************
 * Copyright (c) 2000, 2012 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.tests.resources.usecase;

import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;

/**
 *
 */
public class IFolderTest extends IResourceTest {
	public IFolderTest() {
		super(null);
	}

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

	/**
	 * Tests failure on get/set methods invoked on a nonexistent folder.
	 * Get methods either throw an exception or return null (abnormally).
	 * Set methods throw an exception.
	 */
	protected void nonexistentFolderFailureTests(IFolder folder, IContainer parent, IWorkspace wb) {
		String method = "nonexistentFolderFailureTests(IFolder,IWorkspace)";

		/* Tests for failure in get/set methods in IResource. */
		commonFailureTestsForResource(folder, false);
		assertTrue(method + "4.0", parent.findMember(folder.getName()) == null);

		try {
			IResource[] members = parent.members();
			for (int i = 0; i < members.length; i++) {
				assertTrue("4.1: i=" + i, !members[i].getName().equals(folder.getName()));
			}
		} catch (CoreException e) {
			assertTrue(method + "4.2", false);
		}
		assertTrue(method + "5", !wb.getRoot().exists(folder.getFullPath()));
	}

	public static Test suite() {
		TestSuite suite = new TestSuite(IFolderTest.class.getName());
		suite.addTest(new IFolderTest("testFolder"));
		return suite;
	}

	/**
	 * Create a project in an open solution. Don't open the project.
	 * Contruct a folder handle &amp; check its initial state.
	 * Try creating the folder in the unopened project.
	 * Open the project.
	 * Create the folder &amp; check its state further.
	 * Construct a nested folder handle &amp; check its initial state.
	 * Create the nested folder &amp; check its further.
	 * Delete the nested folder.
	 * Delete the parent folder.
	 * Close the workspace.
	 *
	 * TBD:
	 *
	 * Test deleting a folder that doesn't exist.
	 * Test that deleting a folder recursively deletes all children.
	 * Test deleting a folder the is in a closed project.
	 * Test IResource API
	 * Test IFolder API
	 */
	public void testFolder() {
		IProgressMonitor monitor = null;
		IWorkspace workspace = getWorkspace();

		// Construct a project handle.
		IProject proj = workspace.getRoot().getProject(PROJECT);
		// Construct a folder handle
		IPath path = new Path(FOLDER);

		// Inspection methods with meaninful results invoked on a handle for a nonexistent folder
		// in a nonexistent project.
		IFolder folder = proj.getFolder(path);
		assertTrue("2.1", !folder.exists());
		assertTrue("2.2", folder.getWorkspace().equals(workspace));
		assertTrue("2.4", folder.getProject().equals(proj));
		assertTrue("2.5", folder.getType() == IResource.FOLDER);
		assertTrue("2.6", folder.getFullPath().equals(new Path("/" + PROJECT + "/" + FOLDER)));
		assertTrue("2.7", folder.getName().equals(FOLDER));
		assertTrue("2.8", workspace.getRoot().getFolder(folder.getFullPath()).equals(folder));
		assertTrue("2.10", proj.getFolder(path).equals(folder));
		assertTrue("2.11", folder.getParent().equals(proj));
		assertTrue("2.13", folder.getProjectRelativePath().equals(new Path(FOLDER)));

		// Create a project without opening it.
		try {
			proj.create(monitor);
		} catch (CoreException e) {
			fail("3", e);
		}

		// These tests produce failure because the project is not open yet.
		unopenedProjectFailureTests(folder, proj, workspace);

		// Open project.
		try {
			proj.open(monitor);
		} catch (CoreException e) {
			fail("4", e);
		}

		// These tests produce failure because the folder does not exist yet.
		nonexistentFolderFailureTests(folder, proj, workspace);
		Path absolutePath = new Path(proj.getLocation().toOSString() + "/" + FOLDER);
		assertTrue("5", folder.getLocation().equals(absolutePath));

		// Now create folder.
		try {
			folder.create(false, true, monitor);
		} catch (CoreException e) {
			fail("6", e);
		}

		// The tests that failed above (becaues the folder must exist) now pass.
		assertTrue("7.0", folder.exists());
		assertTrue("7.1", workspace.getRoot().findMember(folder.getFullPath()).exists());
		assertTrue("7.3", workspace.getRoot().findMember(folder.getFullPath()).equals(folder));
		assertTrue("7.4", workspace.getRoot().exists(folder.getFullPath()));
		assertTrue("7.5", folder.getLocation().equals(absolutePath));

		// Session Property
		try {
			assertTrue("8.0", folder.getSessionProperty(Q_NAME_SESSION) == null);
		} catch (CoreException e) {
			fail("8.1");
		}
		try {
			folder.setSessionProperty(Q_NAME_SESSION, STRING_VALUE);
		} catch (CoreException e) {
			fail("8.2");
		}
		try {
			assertTrue("8.3", folder.getSessionProperty(Q_NAME_SESSION).equals(STRING_VALUE));
		} catch (CoreException e) {
			fail("8.4");
		}
		try {
			folder.setSessionProperty(Q_NAME_SESSION, null);
		} catch (CoreException e) {
			fail("8.5");
		}
		try {
			assertTrue("8.6", folder.getSessionProperty(Q_NAME_SESSION) == null);
		} catch (CoreException e) {
			fail("8.7");
		}

		// IResource.isLocal(int)
		// There is no server (yet) so everything should be local.
		assertTrue("9.1", folder.isLocal(IResource.DEPTH_ZERO));
		// No kids, but it should still answer yes.
		assertTrue("9.2", folder.isLocal(IResource.DEPTH_ONE));
		assertTrue("9.3", folder.isLocal(IResource.DEPTH_INFINITE));
		// These guys have kids.
		assertTrue("9.4", proj.isLocal(IResource.DEPTH_ONE));
		assertTrue("9.5", proj.isLocal(IResource.DEPTH_INFINITE));

		// Construct a nested folder handle.
		IFolder nestedFolder = getWorkspace().getRoot().getFolder(folder.getFullPath().append(FOLDER));

		// Inspection methods with meaninful results invoked on a handle for a nonexistent folder.
		assertTrue("10.0", !nestedFolder.exists());
		assertTrue("10.1", nestedFolder.getWorkspace().equals(workspace));
		assertTrue("10.3", nestedFolder.getProject().equals(proj));
		assertTrue("10.4", nestedFolder.getType() == IResource.FOLDER);
		assertTrue("10.5", nestedFolder.getFullPath().equals(new Path("/" + PROJECT + "/" + FOLDER + "/" + FOLDER)));
		assertTrue("10.6", nestedFolder.getName().equals(FOLDER));
		assertTrue("10.7", workspace.getRoot().getFolder(nestedFolder.getFullPath()).equals(nestedFolder));
		IPath projRelativePath = new Path(FOLDER + "/" + FOLDER);
		assertTrue("10.9", proj.getFolder(projRelativePath).equals(nestedFolder));
		assertTrue("10.10", nestedFolder.getParent().equals(folder));
		assertTrue("10.11", nestedFolder.getProjectRelativePath().equals(new Path(FOLDER + "/" + FOLDER)));
		// Now the parent folder has a kid.
		assertTrue("10.12", folder.isLocal(IResource.DEPTH_ONE));
		assertTrue("10.13", folder.isLocal(IResource.DEPTH_INFINITE));

		// These tests produce failure because the nested folder does not exist yet.
		nonexistentFolderFailureTests(nestedFolder, folder, workspace);

		// Create the nested folder.
		try {
			nestedFolder.create(false, true, monitor);
		} catch (CoreException e) {
			fail("11", e);
		}

		// The tests that failed above (becaues the folder must exist) now pass.
		assertTrue("12.0", workspace.getRoot().exists(nestedFolder.getFullPath()));
		assertTrue("12.1", nestedFolder.exists());
		assertTrue("12.2", folder.findMember(nestedFolder.getName()).exists());
		assertTrue("12.4", workspace.getRoot().findMember(nestedFolder.getFullPath()).equals(nestedFolder));
		assertTrue("12.5", workspace.getRoot().exists(nestedFolder.getFullPath()));
		assertTrue("12.6", nestedFolder.getLocation().equals(absolutePath.append(FOLDER)));

		// Delete the nested folder
		try {
			nestedFolder.delete(false, monitor);
		} catch (CoreException e) {
			fail("13.0", e);
		}
		assertTrue("13.1", !nestedFolder.exists());
		try {
			assertTrue("13.2", folder.members().length == 0);
		} catch (CoreException e) {
			fail("13.3");
		}
		assertTrue("13.4", workspace.getRoot().findMember(nestedFolder.getFullPath()) == null);
		assertTrue("13.5", !workspace.getRoot().exists(nestedFolder.getFullPath()));
		assertTrue("13.6", nestedFolder.getLocation().equals(absolutePath.append(FOLDER)));

		// These tests produce failure because the nested folder no longer exists.
		nonexistentFolderFailureTests(nestedFolder, folder, workspace);

		// Parent is still there.
		assertTrue("14.0", folder.exists());
		assertTrue("14.1", workspace.getRoot().findMember(folder.getFullPath()).exists());
		assertTrue("14.3", workspace.getRoot().findMember(folder.getFullPath()).equals(folder));
		assertTrue("14.4", workspace.getRoot().exists(folder.getFullPath()));
		assertTrue("14.5", folder.getLocation().equals(absolutePath));

		// Delete the parent folder
		try {
			folder.delete(false, monitor);
		} catch (CoreException e) {
			fail("15.0", e);
		}
		assertTrue("15.1", !folder.exists());
		assertTrue("15.4", workspace.getRoot().findMember(folder.getFullPath()) == null);
		assertTrue("15.5", !workspace.getRoot().exists(folder.getFullPath()));
		assertTrue("15.6", folder.getLocation().equals(absolutePath));

		// These tests produce failure because the parent folder no longer exists.
		nonexistentFolderFailureTests(folder, proj, workspace);

		try {
			proj.delete(true, true, getMonitor());
		} catch (CoreException e) {
			fail("20.0", e);
		}
	}

	/**
	 * Tests failure on get/set methods invoked on a nonexistent folder.
	 * Get methods either throw an exception or return null (abnormally).
	 * Set methods throw an exception.
	 */
	protected void unopenedProjectFailureTests(IFolder folder, IContainer parent, IWorkspace wb) {
		String method = "unopenedProjectFailureTests(IFolder,IWorkspace)";
		IProgressMonitor monitor = null;

		/* Try creating a folder in a project which is not yet open. */
		try {
			folder.create(false, true, monitor);
			fail(method + "1");
		} catch (CoreException e) {
			// expected
		}
		assertTrue(method + "2", !wb.getRoot().exists(folder.getFullPath()));
	}
}
