/*******************************************************************************
 * 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
 *     Alexander Kurtakov <akurtako@redhat.com> - Bug 459343
 *******************************************************************************/
package org.eclipse.core.tests.internal.watson;

import java.util.Random;
import java.util.Vector;
import org.eclipse.core.internal.watson.*;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;

/**
 * Framework for running tests on element tree components.
 * Supplies convenience methods and some representative element trees.
 */
abstract class TestUtil extends WatsonTest implements IPathConstants {
	public TestUtil(String name) {
		super(name);
	}

	static final IElementComparator fComparator = TestElementComparator.getComparator();

	/**
	 * Asserts that the given comparison value has the added
	 * bit set, and the changed/removed bits blank
	 */
	static void assertAdded(int compare) {
		assertTrue(compare == TestElementComparator.ADDED);
	}

	/**
	 * Asserts that the given comparison value has the changed
	 * bit set, and the added/removed bits blank
	 */
	static void assertChanged(int compare) {
		assertTrue(compare == TestElementComparator.CHANGED);
	}

	/**
	 * Asserts that two trees are equal. If they are not
	 * an AssertionFailedError is thrown.
	 * @param message the detail message for this assertion
	 * @param expected the expected value of a tree
	 * @param actual the actual value of a tree
	 */
	static protected void assertEqualTrees(String message, ElementTree expected, ElementTree actual) {
		assertEqualTrees(message, expected, actual, Path.ROOT, ElementTreeWriter.D_INFINITE);
	}

	/**
	 * Asserts that two trees are equal. If they are not
	 * an AssertionFailedError is thrown.
	 * @param message the detail message for this assertion
	 * @param expected the expected value of a tree
	 * @param actual the actual value of a tree
	 * @param depth The depth to compare to.
	 */
	static protected void assertEqualTrees(String message, ElementTree expected, ElementTree actual, int depth) {
		assertEqualTrees(message, expected, actual, Path.ROOT, depth);
	}

	/**
	 * Asserts that two trees are equal from the given path downwards. If they are not
	 * an AssertionFailedError is thrown.
	 * @param message the detail message for this assertion
	 * @param expected the expected value of a tree
	 * @param actual the actual value of a tree
	 */
	static protected void assertEqualTrees(String message, ElementTree expected, ElementTree actual, IPath path) {
		assertEqualTrees(message, expected, actual, path, ElementTreeWriter.D_INFINITE);
	}

	/**
	 * Asserts that two trees are equal. If they are not
	 * an AssertionFailedError is thrown.
	 * @param message the detail message for this assertion
	 * @param expected the expected value of a tree
	 * @param actual the actual value of a tree
	 * @param depth The depth to compare to.
	 */
	static protected void assertEqualTrees(String msg, ElementTree expected, ElementTree actual, IPath path, int depth) {
		/* check node at current path */
		assertTrue(msg, expected.includes(path));
		assertTrue(msg, actual.includes(path));
		assertEquals(msg, expected.getElementData(path), actual.getElementData(path));

		if (depth != 0) {
			/* get the children */
			IPath[] expectedChildren = expected.getChildren(path);
			IPath[] actualChildren = actual.getChildren(path);
			assertTrue("Number of children", expectedChildren.length == actualChildren.length);

			int newDepth = depth;
			if (depth != ElementTreeWriter.D_INFINITE) {
				--newDepth;
			}
			for (int i = 0; i < expectedChildren.length; i++) {
				assertEquals("children IDs", expectedChildren[i], actualChildren[i]);
				assertEqualTrees("Recursive call", expected, actual, expectedChildren[i], newDepth);
			}
		}
	}

	/**
	 * Asserts that the given tree contains all of the given paths
	 */
	static protected void assertHasPaths(ElementTree tree, IPath[] paths) {
		for (int i = 0; i < paths.length; i++) {
			assertTrue("assertHasPaths" + i, tree.includes(paths[i]));
		}
	}

	/**
	 * Asserts that the given comparison value has the changed
	 * bit set, and the added/removed bits blank
	 */
	static void assertNoChange(int compare) {
		assertTrue(compare == 0);
	}

	/**
	 * Asserts that the given tree doesn not contain all of the given paths
	 */
	static protected void assertNoPaths(ElementTree tree, IPath[] paths) {
		for (int i = 0; i < paths.length; i++) {
			assertTrue("assertNoPaths: " + paths[i], !tree.includes(paths[i]));
		}
	}

	/**
	 * Asserts that the given comparison value has the removed
	 * bit set, and the changed/added bits blank
	 */
	static void assertRemoved(int compare) {
		assertTrue(compare == TestElementComparator.REMOVED);
	}

	/**
	 * Asserts that the Test ElementTree has its original structure
	 */
	static protected void assertTreeStructure(ElementTree tree) {
		assertHasPaths(tree, getTreePaths());

		IPath[] children = tree.getChildren(Path.ROOT);
		assertTrue(children.length == 1);

		/* solution children */
		children = tree.getChildren(children[0]);
		assertTrue(children.length == 2);
		assertTrue(tree.getChildren(project1).length == 0);

		/* project2 children */
		children = tree.getChildren(children[1]);
		assertTrue(children.length == 3);
		assertTrue(tree.getChildren(file1).length == 0);
		assertTrue(tree.getChildren(folder2).length == 0);

		/* folder1 children */
		children = tree.getChildren(children[1]);
		assertTrue(children.length == 3);
		assertTrue(tree.getChildren(file2).length == 0);
		assertTrue(tree.getChildren(folder4).length == 0);

		/* folder3 children */
		children = tree.getChildren(children[1]);
		assertTrue(children.length == 1);
		assertTrue(tree.getChildren(file3).length == 0);
	}

	static ElementTree createTestElementTree() {
		/**
		 * This is a sample element tree on which tests are performed.
		 * The Paths in this tree are found in IPathConstants.  The tree's
		 * basic structure is as follows:
		 *	solution
		 *		project1
		 *		project2
		 *			file1
		 *			folder1
		 *				file2
		 *				folder3
		 *					file3
		 *				folder4
		 *			folder2
		 */

		ElementTree tree = new ElementTree();
		tree.createElement(solution, new String("solution"));
		tree.createElement(project1, new String("project1"));
		tree.createElement(project2, new String("project2"));
		tree.createElement(file1, new String("file1"));
		tree.createElement(folder1, new String("folder1"));
		tree.createElement(folder2, new String("folder2"));
		tree.createElement(file2, new String("file2"));
		tree.createElement(folder3, new String("folder3"));
		tree.createElement(folder4, new String("folder4"));
		tree.createElement(file3, new String("file3"));

		return tree;
	}

	/**
	 * Does several routine operations on the subtree rooted at
	 * the given path.  Opens a new delta after every operation.
	 * Returns an array of all the intermediary ElementTrees.
	 */
	static protected ElementTree[] doManyRoutineOperations(ElementTree tree, IPath path) {
		Vector<ElementTree> trees = new Vector<>();
		trees.addElement(tree);

		int repeat = 1;

		/* create file elements */
		tree = tree.newEmptyDelta();
		IPath[] files = getFilePaths(path);
		for (IPath file : files) {
			Object data = file.toString();
			tree.createElement(file, data);

			tree.immutable();
			trees.addElement(tree);
			tree = tree.newEmptyDelta();
		}

		/* modify the data of all file elements a few times */
		for (int i = 0; i < repeat; i++) {
			Object data = "data" + i;
			for (IPath file : files) {
				tree.setElementData(file, data);
				tree.immutable();
				trees.addElement(tree);
				tree = tree.newEmptyDelta();
			}
		}

		/* delete all file elements */
		for (IPath file : files) {
			tree.deleteElement(file);
			tree.immutable();
			trees.addElement(tree);
			tree = tree.newEmptyDelta();
		}

		ElementTree[] results = new ElementTree[trees.size()];
		trees.copyInto(results);
		return results;
	}

	/**
	 * Does several routine operations on the subtree rooted at
	 * the given path.  Returns an array of all the intermediary elementtrees.
	 */
	static protected ElementTree[] doRoutineOperations(ElementTree tree, IPath path) {
		Vector<ElementTree> trees = new Vector<>();
		trees.addElement(tree);

		int repeat = 1;

		/* create file elements */
		tree = tree.newEmptyDelta();
		IPath[] files = getFilePaths(path);
		for (IPath file : files) {
			Object data = file.toString();

			tree.createElement(file, data);
		}

		tree.immutable();
		trees.addElement(tree);
		tree = tree.newEmptyDelta();

		/* modify the data of all file elements a few times */
		for (int i = 0; i < repeat; i++) {
			Object data = "data" + i;
			for (IPath file : files) {
				tree.setElementData(file, data);
			}
		}

		tree.immutable();
		trees.addElement(tree);
		tree = tree.newEmptyDelta();

		/* delete all file elements */
		for (IPath file : files) {
			tree.deleteElement(file);
		}

		tree.immutable();
		trees.addElement(tree);

		ElementTree[] results = new ElementTree[trees.size()];
		trees.copyInto(results);
		return results;
	}

	/**
	 * Returns an element tree comparator
	 */
	static IElementComparator getComparator() {
		return fComparator;
	}

	/**
	 * Returns an array of paths below the given path.
	 */
	static protected IPath[] getFilePaths(IPath project3) {
		String[] names = getJavaLangUnits();
		IPath[] paths = new IPath[names.length];
		for (int i = 0; i < paths.length; i++) {
			paths[i] = project3.append(names[i]);
		}
		return paths;
	}

	/**
	 * Returns strings representing javalang classes
	 */
	static protected String[] getJavaLangUnits() {
		return new String[] {"AbstractMethodError.java", "ArithmeticException.java", "ArrayIndexOutOfBoundsException.java", "ArrayStoreException.java", "Boolean.java", "Byte.java", "Character.java", "Class.java", "ClassCastException.java", "ClassCircularityError.java", "ClassFormatError.java", "ClassLoader.java", "ClassNotFoundException.java", "Cloneable.java", "CloneNotSupportedException.java", "Compiler.java", "Double.java", "Error.java",};
	}

	/**
	 * Returns the paths for all the elements in the tree in top-down order
	 */
	static protected IPath[] getTreePaths() {
		return new IPath[] {solution, project1, project2, folder1, folder2, folder3, folder4, file1, file2, file3};
	}

	/**
	 * Randomly scrambles an array.
	 */
	static protected void scramble(Object[] first) {
		Random random = new Random(System.currentTimeMillis());

		final int len = first.length;
		for (int i = 0; i < len * 100; i++) {
			/* get any array offset */
			int off1 = (int) (random.nextFloat() * len);
			if (off1 == len) {
				continue;
			}

			/* get another array offset */
			int off2 = (int) (random.nextFloat() * len);
			if (off2 == len) {
				continue;
			}

			/* switch */
			Object temp = first[off1];
			first[off1] = first[off2];
			first[off2] = temp;
		}
	}

	/**
	 * Randomly scrambles two arrays, ensuring that both
	 * arrays undergo the same permutation.
	 */
	static protected void scramble(Object[] first, Object[] second) {
		assertTrue(first.length == second.length);
		Random random = new Random(System.currentTimeMillis());

		final int len = first.length;
		for (int i = 0; i < len * 100; i++) {
			/* get any array offset */
			int off1 = (int) (random.nextFloat() * len);
			if (off1 == len) {
				continue;
			}

			/* get another array offset */
			int off2 = (int) (random.nextFloat() * len);
			if (off2 == len) {
				continue;
			}

			/* switch */
			Object temp = first[off1];
			first[off1] = first[off2];
			first[off2] = temp;

			temp = second[off1];
			second[off1] = second[off2];
			second[off2] = temp;
		}
	}

}
