/*******************************************************************************
 * Copyright (c) 2000, 2012 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.ByteArrayInputStream;
import java.io.InputStream;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.tests.resources.ResourceTest;

/**
 * Tests regression of bug 25457.  In this case, attempting to move a project
 * that is only a case change, where the move fails due to another handle being
 * open on a file in the hierarchy, would cause deletion of the source.
 *
 * Note: this is similar to Bug_32076, which deals with failure to move in
 * the non case-change scenario.
 */
public class Bug_025457 extends ResourceTest {
	public static Test suite() {
		return new TestSuite(Bug_025457.class);
	}

	public Bug_025457() {
		super();
	}

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

	public void testFile() {
		//this test only works on windows
		if (!isWindows()) {
			return;
		}
		IProject source = getWorkspace().getRoot().getProject("project");
		IFile sourceFile = source.getFile("file.txt");
		IFile destFile = source.getFile("File.txt");
		ensureExistsInWorkspace(source, true);
		final String content = getRandomString();
		ensureExistsInWorkspace(sourceFile, content);

		//open a stream in the source to cause the rename to fail
		InputStream stream = null;
		try {
			try {
				stream = sourceFile.getContents();
			} catch (CoreException e) {
				fail("0.99", e);
			}
			//try to rename the file (should fail)
			try {
				sourceFile.move(destFile.getFullPath(), IResource.NONE, getMonitor());
				fail("1.99");
			} catch (CoreException e1) {
				//should fail
			}
		} finally {
			assertClose(stream);
		}
		//ensure source still exists and has same content
		assertTrue("2.0", source.exists());
		assertTrue("2.1", sourceFile.exists());
		try {
			stream = sourceFile.getContents();
			assertTrue("2.2", compareContent(stream, new ByteArrayInputStream(content.getBytes())));
		} catch (CoreException e) {
			fail("3.99", e);
		} finally {
			assertClose(stream);
		}
		//ensure destination file does not exist
		assertTrue("2.3", !destFile.exists());
	}

	public void testFolder() {
		//this test only works on windows
		//native code must also be present so move can detect the case change
		if (!isWindows() || !isReadOnlySupported()) {
			return;
		}
		IProject source = getWorkspace().getRoot().getProject("SourceProject");
		IFolder sourceFolder = source.getFolder("folder");
		IFile sourceFile = sourceFolder.getFile("Important.txt");
		IFolder destFolder = source.getFolder("Folder");
		IFile destFile = destFolder.getFile("Important.txt");
		ensureExistsInWorkspace(source, true);
		ensureExistsInWorkspace(sourceFolder, true);
		ensureExistsInWorkspace(sourceFile, true);

		//open a stream in the source to cause the rename to fail
		InputStream stream = null;
		try {
			try {
				stream = sourceFile.getContents();
			} catch (CoreException e) {
				fail("0.99", e);
			}
			//try to rename the project (should fail)
			try {
				sourceFolder.move(destFolder.getFullPath(), IResource.NONE, getMonitor());
				fail("1.99");
			} catch (CoreException e1) {
				//should fail
			}
			//ensure source still exists
			assertTrue("2.0", source.exists());
			assertTrue("2.1", sourceFolder.exists());
			assertTrue("2.2", sourceFile.exists());

			//ensure destination does not exist
			assertTrue("2.3", !destFolder.exists());
			assertTrue("2.4", !destFile.exists());

		} finally {
			assertClose(stream);
		}
	}

	public void testProject() {
		//this test only works on windows
		if (!isWindows()) {
			return;
		}
		IProject source = getWorkspace().getRoot().getProject("project");
		IProject destination = getWorkspace().getRoot().getProject("Project");
		IFile sourceFile = source.getFile("Important.txt");
		IFile destFile = destination.getFile("Important.txt");
		ensureExistsInWorkspace(source, true);
		ensureExistsInWorkspace(sourceFile, true);

		//open a stream in the source to cause the rename to fail
		InputStream stream = null;
		try {
			try {
				stream = sourceFile.getContents();
			} catch (CoreException e) {
				fail("1.99", e);
			}
			//try to rename the project (should fail)
			try {
				source.move(destination.getFullPath(), IResource.NONE, getMonitor());
				fail("1.99");
			} catch (CoreException e1) {
				//should fail
			}
			//ensure source does not exist
			assertTrue("2.0", !source.exists());
			assertTrue("2.1", !sourceFile.exists());

			//ensure destination does not exist
			assertTrue("2.2", destination.exists());
			assertTrue("2.3", destFile.exists());

		} finally {
			assertClose(stream);
		}
	}
}
