/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *     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;
		}
	}

}
