/*******************************************************************************
 * Copyright (c) 2000, 2006 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.objectteams.otdt.tests;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.StringTokenizer;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.compiler.batch.Main;
import org.eclipse.jdt.internal.core.JavaElement;
import org.eclipse.objectteams.otdt.tests.AbstractJavaModelTests;

/*
 * Tests that modify resources in the workspace.
 */
//{OT_COPY_PASTE: class copied from org.eclipse.jdt.core.tests.model
public class ModifyingResourceTests extends AbstractJavaModelTests {
	
public ModifyingResourceTests(String name) {
	super(name);
}
protected void assertDeltas(String message, String expected) {
	StringBuffer buffer = new StringBuffer();
	IJavaElementDelta[] deltas = this.deltaListener.deltas;
	for (int i=0, length= deltas.length; i<length; i++) {
		IJavaElementDelta[] projects = deltas[i].getAffectedChildren();
		this.sortDeltas(projects);
		for (int j=0, projectsLength=projects.length; j<projectsLength; j++) {
			buffer.append(projects[j]);
			if (j != projectsLength-1) {
				buffer.append("\n");
			}
		}
		IResourceDelta[] nonJavaProjects = deltas[i].getResourceDeltas();
		if (nonJavaProjects != null) {
			for (int j=0, nonJavaProjectsLength=nonJavaProjects.length; j<nonJavaProjectsLength; j++) {
				if (j == 0 && buffer.length() != 0) {
					buffer.append("\n");
				}
				buffer.append(nonJavaProjects[j]);
				if (j != nonJavaProjectsLength-1) {
					buffer.append("\n");
				}
			}
		}
		if (i != length-1) {
			buffer.append("\n\n");
		}
	}
	String actual = buffer.toString();
	if (!expected.equals(actual)) {
		System.out.println(displayString(actual, 2));
	}
	assertEquals(
		message,
		expected,
		actual);
}
protected void assertElementDescendants(String message,  String expected, IJavaElement element) throws CoreException {
	String actual = expandAll(element);
	if (!expected.equals(actual)){
	 	System.out.println(Util.displayString(actual, 4));
	}
	assertEquals(
		message,
		expected,
		actual);
}
/**
 * E.g. <code>
 * org.eclipse.jdt.tests.core.ModifyingResourceTests.generateClassFile(
 *   "A",
 *   "public class A {\n" +
 *   "}")
 */
public static void generateClassFile(String className, String javaSource) throws IOException {
	String cu = "d:/temp/" + className + ".java";
	FileOutputStream output = new FileOutputStream(cu);
	try {
		output.write(javaSource.getBytes());
	} finally {
		output.close();
	}
	Main.compile(cu + " -d d:/temp -classpath " + System.getProperty("java.home") + "/lib/rt.jar");
	FileInputStream input = new FileInputStream("d:/temp/" + className + ".class");
	try {
		System.out.println("{");
		byte[] buffer = new byte[80];
		int read = 0;
		while (read != -1) {
			read = input.read(buffer);
			if (read != -1) System.out.print("\t");
			for (int i = 0; i < read; i++) {
				System.out.print(buffer[i]);
				System.out.print(", ");	
			}
			if (read != -1) System.out.println();
		}
		System.out.print("}");
	} finally {
		input.close();
	}
}

protected IFile createFile(String path, InputStream content) throws CoreException {
	IFile file = this.getFile(path);
	file.create(content, true, null);
	return file;
}

protected IFile createFile(String path, byte[] content) throws CoreException {
	IFile file = this.getFile(path);
	InputStream input = new ByteArrayInputStream(content);
	file.create(input, true, null);
	return file;
}

protected IFile createFile(String path, String content) throws CoreException {
	IFile file = this.getFile(path);
	InputStream input = new ByteArrayInputStream(content.getBytes());
	file.create(input, true, null);
	return file;
}
protected IFolder createFolder(String path) throws CoreException {
	final IFolder folder = this.getFolder(path);
	getWorkspace().run(new IWorkspaceRunnable() {
		public void run(IProgressMonitor monitor) throws CoreException {
			IContainer parent = folder.getParent();
			if (parent instanceof IFolder && !parent.exists()) {
				createFolder(parent.getFullPath().toString());
			} 
			folder.create(true, true, null);
		}
	},
	null);

	return folder;
}
protected void deleteFile(String filePath) throws CoreException {
	deleteResource(this.getFile(filePath));
}
protected void deleteFolder(String folderPath) throws CoreException {
	deleteResource(this.getFolder(folderPath));
}
protected IFile editFile(String path, String content) throws CoreException {
	IFile file = this.getFile(path);
	InputStream input = new ByteArrayInputStream(content.getBytes());
	file.setContents(input, IResource.FORCE, null);
	return file;
}
/* 
 * Expands (i.e. open) the given element and returns a toString() representation
 * of the tree.
 */
protected String expandAll(IJavaElement element) throws CoreException {
	StringBuffer buffer = new StringBuffer();
	this.expandAll(element, 0, buffer);
	return buffer.toString();
}
private void expandAll(IJavaElement element, int tab, StringBuffer buffer) throws CoreException {
	IJavaElement[] children = null;
	// force opening of element by getting its children
	if (element instanceof IParent) {
		IParent parent = (IParent)element;
		children = parent.getChildren();
	}
	((JavaElement)element).toStringInfo(tab, buffer);
	if (children != null) {
		for (int i = 0, length = children.length; i < length; i++) {
			buffer.append("\n");
			this.expandAll(children[i], tab+1, buffer);
		}
	}
}
protected void renameProject(String project, String newName) throws CoreException {
	this.getProject(project).move(new Path(newName), true, null);
}
protected void sortDeltas(IJavaElementDelta[] deltas) {
	org.eclipse.jdt.internal.core.util.Util.Comparer comparer = new org.eclipse.jdt.internal.core.util.Util.Comparer() {
		public int compare(Object a, Object b) {
			IJavaElementDelta deltaA = (IJavaElementDelta)a;
			IJavaElementDelta deltaB = (IJavaElementDelta)b;
			return deltaA.getElement().getElementName().compareTo(deltaB.getElement().getElementName());
		}
	};
	org.eclipse.jdt.internal.core.util.Util.sort(deltas, comparer);
}
protected IClassFile getClassFile(String path) {
	return (IClassFile)JavaCore.create(getFile(path));
}
protected IFolder getFolder(String path) {
	return getWorkspaceRoot().getFolder(new Path(path));
}
protected IPackageFragment getPackage(String path) {
	if (path.indexOf('/', 1) != -1) { // if path as more than one segment
		IJavaElement element = JavaCore.create(this.getFolder(path));
		if (element instanceof IPackageFragmentRoot) {
			return ((IPackageFragmentRoot)element).getPackageFragment("");
		}
		return (IPackageFragment)element;
	}
	IProject project = this.getProject(path);
	return JavaCore.create(project).getPackageFragmentRoot(project).getPackageFragment("");
}
protected IPackageFragmentRoot getPackageFragmentRoot(String path) {
	if (path.indexOf('/', 1) != -1) { // if path as more than one segment
		if (path.endsWith(".jar")) {
			return  (IPackageFragmentRoot)JavaCore.create(this.getFile(path));
		}
		return (IPackageFragmentRoot)JavaCore.create(this.getFolder(path));
	}
	IProject project = this.getProject(path);
	return JavaCore.create(project).getPackageFragmentRoot(project);
}
protected String getSortedByProjectDeltas() {
	StringBuffer buffer = new StringBuffer();
	for (int i=0, length = this.deltaListener.deltas.length; i<length; i++) {
		IJavaElementDelta[] projects = this.deltaListener.deltas[i].getAffectedChildren();
		int projectsLength = projects.length;
		
		// sort by project
		IJavaElementDelta[] sorted = new IJavaElementDelta[projectsLength];
		System.arraycopy(projects, 0, sorted, 0, projectsLength);
		org.eclipse.jdt.internal.core.util.Util.sort(
			sorted, 
			new  org.eclipse.jdt.internal.core.util.Util.Comparer() {
				public int compare(Object a, Object b) {
					return a.toString().compareTo(b.toString());
				}
			});
		
		for (int j=0; j<projectsLength; j++) {
			buffer.append(sorted[j]);
			if (j != projectsLength-1) {
				buffer.append("\n");
			}
		}
		if (i != length-1) {
			buffer.append("\n\n");
		}
	}
	return buffer.toString();
}
protected void moveFile(String sourcePath, String destPath) throws CoreException {
	this.getFile(sourcePath).move(this.getFile(destPath).getFullPath(), false, null);
}
protected void moveFolder(String sourcePath, String destPath) throws CoreException {
	this.getFolder(sourcePath).move(this.getFolder(destPath).getFullPath(), false, null);
}
protected void swapFiles(String firstPath, String secondPath) throws CoreException {
	final IFile first = this.getFile(firstPath);
	final IFile second = this.getFile(secondPath);
	IWorkspaceRunnable runnable = new IWorkspaceRunnable(	) {
		public void run(IProgressMonitor monitor) throws CoreException {
			IPath tempPath = first.getParent().getFullPath().append("swappingFile.temp");
			first.move(tempPath, false, monitor);
			second.move(first.getFullPath(), false, monitor);
			getWorkspaceRoot().getFile(tempPath).move(second.getFullPath(), false, monitor);
		}
	};
	getWorkspace().run(runnable, null);
}
/*
 * Returns a new classpath from the given source folders and their respective exclusion patterns.
 * The given array as the following form:
 * [<source folder>, "<pattern>[|<pattern]*"]*
 * E.g. new String[] {
 *   "src1", "p/A.java",
 *   "src2", "*.txt|com.tests/**"
 * }
 */
protected IClasspathEntry[] createClasspath(String[] sourceFoldersAndPatterns, boolean hasInclusionPatterns, boolean hasExclusionPatterns) {
	int length = sourceFoldersAndPatterns.length;
	int increment = 1;
	if (hasInclusionPatterns) increment++;
	if (hasExclusionPatterns) increment++;
	IClasspathEntry[] classpath = new IClasspathEntry[length/increment];
	for (int i = 0; i < length; i+=increment) {
		String src = sourceFoldersAndPatterns[i];
		IPath[] inclusionPatternPaths = new IPath[0];
		if (hasInclusionPatterns) {
			String patterns = sourceFoldersAndPatterns[i+1];
			StringTokenizer tokenizer = new StringTokenizer(patterns, "|");
			int patternsCount =  tokenizer.countTokens();
			inclusionPatternPaths = new IPath[patternsCount];
			for (int j = 0; j < patternsCount; j++) {
				inclusionPatternPaths[j] = new Path(tokenizer.nextToken());
			}
		}
		IPath[] exclusionPatternPaths = new IPath[0];
		if (hasExclusionPatterns) {
			String patterns = sourceFoldersAndPatterns[i+increment-1];
			StringTokenizer tokenizer = new StringTokenizer(patterns, "|");
			int patternsCount =  tokenizer.countTokens();
			exclusionPatternPaths = new IPath[patternsCount];
			for (int j = 0; j < patternsCount; j++) {
				exclusionPatternPaths[j] = new Path(tokenizer.nextToken());
			}
		}
		classpath[i/increment] = JavaCore.newSourceEntry(new Path(src), inclusionPatternPaths, exclusionPatternPaths, null); 
	}
	return classpath;
}

}
//ike}