/*******************************************************************************
 * 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.resources;

import java.io.*;
import java.net.URI;
import java.util.*;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.internal.resources.*;
import org.eclipse.core.internal.utils.FileUtil;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;

/**
 * Tests path variables.
 */
public class IPathVariableTest extends ResourceTest {

	IPathVariableManager manager = null;
	IProject project = null;

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		project = getWorkspace().getRoot().getProject("MyProject");
		try {
			project.create(getMonitor());
			project.open(getMonitor());
		} catch (CoreException e) {
			fail("1.3", e);
		}
		assertTrue("1.4", project.exists());
		manager = project.getPathVariableManager();
	}

	class PathVariableChangeVerifier implements IPathVariableChangeListener {
		class VerificationFailedException extends Exception {
			/**
			 * All serializable objects should have a stable serialVersionUID
			 */
			private static final long serialVersionUID = 1L;

			VerificationFailedException(String message) {
				super(message);
			}
		}

		class Event {
			int type;
			String name;
			IPath value;

			Event(int type, String name, IPath value) {
				this.type = type;
				this.name = name;
				this.value = value;
			}

			@Override
			public boolean equals(Object obj) {
				if (obj == null || !(obj instanceof Event)) {
					return false;
				}
				Event that = (Event) obj;
				if (this.type != that.type || !this.name.equals(that.name)) {
					return false;
				}
				return this.value == null ? that.value == null : this.value.equals(that.value);
			}

			@Override
			public String toString() {
				StringBuffer buffer = new StringBuffer();
				buffer.append("Event(");
				buffer.append("type: ");
				buffer.append(stringForType(type));
				buffer.append(" name: ");
				buffer.append(name);
				buffer.append(" value: ");
				buffer.append(value);
				buffer.append(")");
				return buffer.toString();
			}

			String stringForType(int typeValue) {
				switch (typeValue) {
					case IPathVariableChangeEvent.VARIABLE_CREATED :
						return "CREATED";
					case IPathVariableChangeEvent.VARIABLE_CHANGED :
						return "CHANGED";
					case IPathVariableChangeEvent.VARIABLE_DELETED :
						return "DELETED";
					default :
						return "UNKNOWN";
				}
			}
		}

		List<Event> expected = new ArrayList<>();
		List<Event> actual = new ArrayList<>();

		void addExpectedEvent(int type, String name, IPath value) {
			expected.add(new Event(type, name, value));
		}

		void verify() throws VerificationFailedException {
			String message;
			if (expected.size() != actual.size()) {
				message = "Expected size: " + expected.size() + " does not equal actual size: " + actual.size() + "\n";
				message += dump();
				throw new VerificationFailedException(message);
			}
			for (Event event : expected) {
				if (!actual.contains(event)) {
					message = "Expected and actual results differ.\n";
					message += dump();
					throw new VerificationFailedException(message);
				}
			}
		}

		void reset() {
			expected = new ArrayList<>();
			actual = new ArrayList<>();
		}

		@Override
		public void pathVariableChanged(IPathVariableChangeEvent event) {
			actual.add(new Event(event.getType(), event.getVariableName(), event.getValue()));
		}

		String dump() {
			StringBuffer buffer = new StringBuffer();
			buffer.append("Expected:\n");
			for (Event event : expected) {
				buffer.append("\t" + event + "\n");
			}
			buffer.append("Actual:\n");
			for (Event event : actual) {
				buffer.append("\t" + event + "\n");
			}
			return buffer.toString();
		}
	}

	/**
	 * Default constructor for this class.
	 */
	public IPathVariableTest() {
		super();
	}

	/**
	 * Constructor for the class.
	 */
	public IPathVariableTest(String name) {
		super(name);
	}

	/**
	 * Return the tests to run.
	 *
	 * @see org.eclipse.core.tests.harness.ResourceTest#suite()
	 */
	public static Test suite() {
		return new TestSuite(IPathVariableTest.class);
	}

	/**
	 * Test IPathVariableManager#getPathVariableNames
	 */
	public void testGetPathVariableNames() {
		String[] names = null;

		// add one
		try {
			manager.setValue("one", getRandomLocation());
		} catch (CoreException e) {
			fail("1.0", e);
		}
		names = manager.getPathVariableNames();
		List<String> list = Arrays.asList(names);
		assertTrue("1.2", list.contains("one"));

		// add another
		try {
			manager.setValue("two", Path.ROOT);
		} catch (CoreException e) {
			fail("2.0", e);
		}
		names = manager.getPathVariableNames();
		list = Arrays.asList(names);
		assertTrue("2.2", list.contains("one"));
		assertTrue("2.3", list.contains("two"));

		// remove one
		try {
			manager.setValue("one", (IPath) null);
		} catch (CoreException e) {
			fail("3.0", e);
		}
		names = manager.getPathVariableNames();
		list = Arrays.asList(names);
		assertTrue("3.2", list.contains("two"));
		assertTrue("3.3", !list.contains("one"));

		// remove the last one
		try {
			manager.setValue("two", (IPath) null);
		} catch (CoreException e) {
			fail("4.0", e);
		}
		names = manager.getPathVariableNames();
		list = Arrays.asList(names);
		assertTrue("4.2", !list.contains("two"));
		assertTrue("4.3", !list.contains("one"));
	}

	/**
	 * Test IPathVariableManager#getValue and IPathVariableManager#setValue
	 */
	public void testGetSetValue() {
		boolean WINDOWS = java.io.File.separatorChar == '\\';
		IPath pathOne = WINDOWS ? new Path("C:\\testGetSetValue") : new Path("/testGetSetValue");
		IPath pathTwo = new Path("/blort/backup");
		//add device if necessary
		pathTwo = new Path(pathTwo.toFile().getAbsolutePath());
		IPath pathOneEdit = WINDOWS ? new Path("D:/foobar") : new Path("/foobar");

		// nothing to begin with
		assertNull("0.0", manager.getValue("one"));

		// add a value to the table
		try {
			manager.setValue("one", pathOne);
		} catch (CoreException e) {
			fail("1.0", e);
		}
		IPath value = manager.getValue("one");
		assertNotNull("1.1", value);
		assertEquals("1.2", pathOne, value);

		// add another value
		try {
			manager.setValue("two", pathTwo);
		} catch (CoreException e) {
			fail("2.0", e);
		}
		value = manager.getValue("two");
		assertNotNull("2.1", value);
		assertEquals("2.2", pathTwo, value);

		// edit the first value
		try {
			manager.setValue("one", pathOneEdit);
		} catch (CoreException e) {
			fail("3.0", e);
		}
		value = manager.getValue("one");
		assertNotNull("3.1", value);
		assertTrue("3.2", pathOneEdit.equals(value));

		// setting with value == null will remove
		try {
			manager.setValue("one", (IPath) null);
		} catch (CoreException e) {
			fail("4.0", e);
		}
		assertNull("4.1", manager.getValue("one"));

		// set values with bogus names
		try {
			manager.setValue("ECLIPSE$HOME", Path.ROOT);
			fail("5.0 Accepted invalid variable name in setValue()");
		} catch (CoreException ce) {
			// success
		}

		// set value with relative path
		try {
			manager.setValue("one", new Path("foo/bar"));
		} catch (CoreException ce) {
			fail("5.0 Did not Accepted invalid variable value in setValue()");
		}

		// set invalid value (with invalid segment)
		if (WINDOWS) {
			String invalidPathString = "C:/a/\\::/b";
			IPath invalidPath = Path.fromPortableString(invalidPathString);
			assertTrue("6.0", invalidPath.isAbsolute());
			assertTrue("6.1", !Path.EMPTY.isValidPath(invalidPathString));
			assertTrue("6.2", manager.validateValue(invalidPath).isOK());
			try {
				manager.setValue("one", invalidPath);
			} catch (CoreException ce) {
				fail("6.3 Fail to accept invalid variable value in setValue()");
			}
		}

	}

	/**
	 * Test IPathVariableManager#isDefined
	 */
	public void testIsDefined() {
		assertTrue("0.0", !manager.isDefined("one"));
		try {
			manager.setValue("one", Path.ROOT);
		} catch (CoreException e) {
			fail("1.0", e);
		}
		assertTrue("1.1", manager.isDefined("one"));
		try {
			manager.setValue("one", (IPath) null);
		} catch (CoreException e) {
			fail("2.0", e);
		}
		assertTrue("2.1", !manager.isDefined("one"));
	}

	/**
	 * Test IPathVariableManager#resolvePath
	 */
	public void testResolvePathWithMacro() {
		final boolean WINDOWS = java.io.File.separatorChar == '\\';
		IPath pathOne = WINDOWS ? new Path("c:/testGetSetValue/foo") : new Path("/testGetSetValue/foo");
		IPath pathTwo = WINDOWS ? new Path("c:/tmp/backup") : new Path("/tmp/backup");
		// add device if neccessary
		pathTwo = new Path(pathTwo.toFile().getAbsolutePath());

		try {
			manager.setValue("one", pathOne);
		} catch (CoreException e) {
			fail("0.1", e);
		}
		try {
			manager.setValue("two", pathTwo);
		} catch (CoreException e) {
			fail("0.2", e);
		}

		try {
			manager.setValue("three", Path.fromOSString("${two}/extra"));
		} catch (CoreException e) {
			fail("0.3", e);
		}

		IPath path = new Path("three/bar");
		IPath expected = new Path("/tmp/backup/extra/bar").setDevice(WINDOWS ? "c:" : null);
		IPath actual = manager.resolvePath(path);
		assertEquals("1.0", expected, actual);
	}

	/**
	 */
	public void testProjectLoc() {
		IPath path = new Path("${PROJECT_LOC}/bar");
		IPath projectLocation = project.getLocation();

		IPath expected = projectLocation.append("bar");
		IPath actual = manager.resolvePath(path);
		assertEquals("1.0", expected, actual);
	}

	/**
	 */
	public void testEclipseHome() {
		IPath path = new Path("${ECLIPSE_HOME}/bar");
		IPath expected = new Path(Platform.getInstallLocation().getURL().getPath()).append("bar");
		IPath actual = manager.resolvePath(path);
		assertEquals("1.0", expected, actual);
	}

	/**
	 */
	public void testWorkspaceLocation() {
		IPath path = new Path("${WORKSPACE_LOC}/bar");
		IPath expected = project.getWorkspace().getRoot().getLocation().append("bar");
		IPath actual = manager.resolvePath(path);
		assertEquals("1.0", expected, actual);
	}

	/**
	 * Test IgetVariableRelativePathLocation(project, IPath)
	 */

	public void testGetVariableRelativePathLocation() {
		IPath path = project.getWorkspace().getRoot().getLocation().append("bar");
		IPath actual;
		IPath expected;
		/* Does not work on the test machine because ECLIPSE_HOME and WORKSPACE is the same location
		actual = getVariableRelativePathLocation(project, path);
		expected = new Path("WORKSPACE_LOC/bar");
		assertEquals("1.0", expected, actual);
		 */
		path = new Path(Platform.getInstallLocation().getURL().getPath()).append("bar");
		expected = new Path("ECLIPSE_HOME/bar");
		actual = getVariableRelativePathLocation(project, path);
		assertEquals("2.0", expected, actual);

		path = project.getLocation().append("bar");
		expected = new Path("PROJECT_LOC/bar");
		actual = getVariableRelativePathLocation(project, path);
		assertEquals("3.0", expected, actual);

		actual = getVariableRelativePathLocation(project, new Path("/nonExistentPath/foo"));
		assertEquals("4.0", null, actual);
	}

	private IPath getVariableRelativePathLocation(IProject project, IPath location) {
		URI variableRelativePathLocation = project.getPathVariableManager().getVariableRelativePathLocation(URIUtil.toURI(location));
		if (variableRelativePathLocation != null) {
			return URIUtil.toPath(variableRelativePathLocation);
		}
		return null;
	}

	/**
	 * Test IPathVariableManager#resolvePath
	 */
	public void testResolvePath() {
		final boolean WINDOWS = java.io.File.separatorChar == '\\';
		IPath pathOne = WINDOWS ? new Path("C:/testGetSetValue/foo") : new Path("/testGetSetValue/foo");
		IPath pathTwo = new Path("/blort/backup");
		//add device if necessary
		pathTwo = new Path(pathTwo.toFile().getAbsolutePath());

		try {
			// for WINDOWS - the device id for windows will be changed to upper case
			// in the variable stored in the manager
			manager.setValue("one", pathOne);
		} catch (CoreException e) {
			fail("0.1", e);
		}
		try {
			manager.setValue("two", pathTwo);
		} catch (CoreException e) {
			fail("0.2", e);
		}

		// one substitution
		IPath path = new Path("one/bar");
		IPath expected = new Path("/testGetSetValue/foo/bar").setDevice(WINDOWS ? "C:" : null);
		IPath actual = manager.resolvePath(path);
		assertEquals("1.0", expected, actual);

		// another substitution
		path = new Path("two/myworld");
		expected = new Path("/blort/backup/myworld");
		expected = new Path(expected.toFile().getAbsolutePath());
		actual = manager.resolvePath(path);
		assertEquals("2.0", expected, actual);

		// variable not defined
		path = new Path("three/nothere");
		expected = path;
		actual = manager.resolvePath(path);
		assertEquals("3.0", expected, actual);

		// device
		path = new Path("/one").setDevice(WINDOWS ? "C:" : null);
		expected = path;
		actual = manager.resolvePath(path);
		assertEquals("4.0", expected, actual);

		// device2
		if (WINDOWS) {
			path = new Path("C:two");
			expected = path;
			actual = manager.resolvePath(path);
			assertEquals("5.0", expected, actual);
		}

		// absolute
		path = new Path("/one");
		expected = path;
		actual = manager.resolvePath(path);
		assertEquals("6.0", expected, actual);

		// just resolving, check if the variable stored in the manager is canonicalized
		if (WINDOWS) {
			path = new Path("one");
			expected = FileUtil.canonicalPath(pathOne);
			actual = manager.resolvePath(path);
			// the path stored in the manager is canonicalized, so the device id of actual will be upper case
			assertEquals("7.0", expected, actual);
		}

		// null
		path = null;
		assertNull("7.0", manager.resolvePath(path));

	}

	private IPath convertToRelative(IPathVariableManager manager, IPath path, boolean force, String variableHint) throws CoreException {
		return URIUtil.toPath(manager.convertToRelative(URIUtil.toURI(path), force, variableHint));
	}

	/**
	 * Test IPathVariableManager#convertToRelative()
	 */
	public void testConvertToRelative() {
		final boolean WINDOWS = java.io.File.separatorChar == '\\';
		IPath pathOne = WINDOWS ? new Path("c:/foo/bar") : new Path("/foo/bar");
		IPath pathTwo = WINDOWS ? new Path("c:/foo/other") : new Path("/foo/other");
		IPath pathThree = WINDOWS ? new Path("c:/random/other/subpath") : new Path("/random/other/subpath");
		IPath file = WINDOWS ? new Path("c:/foo/other/file.txt") : new Path("/foo/other/file.txt");

		try {
			manager.setValue("ONE", pathOne);
			manager.setValue("THREE", pathThree);
		} catch (CoreException e) {
			fail("0.1", e);
		}

		IPath actual = null;
		try {
			actual = convertToRelative(manager, file, false, "ONE");
		} catch (CoreException e) {
			fail("0.2", e);
		}
		IPath expected = file;
		assertEquals("1.0", expected, actual);

		try {
			manager.setValue("TWO", pathTwo);
		} catch (CoreException e) {
			fail("1.1", e);
		}

		try {
			actual = convertToRelative(manager, file, false, "ONE");
		} catch (CoreException e) {
			fail("1.2", e);
		}
		expected = file;
		assertEquals("2.0", expected, actual);

		try {
			actual = convertToRelative(manager, file, false, "TWO");
		} catch (CoreException e) {
			fail("2.1", e);
		}
		expected = new Path("TWO/file.txt");
		assertEquals("3.0", expected, actual);

		// force the path to be relative to "ONE"
		try {
			actual = convertToRelative(manager, file, true, "ONE");
		} catch (CoreException e) {
			fail("3.1", e);
		}
		expected = new Path("PARENT-1-ONE/other/file.txt");
		assertEquals("4.0", expected, actual);

		// the second time should be re-using "FOO"
		try {
			actual = convertToRelative(manager, file, true, "ONE");
		} catch (CoreException e) {
			fail("4.3", e);
		}
		expected = new Path("PARENT-1-ONE/other/file.txt");
		assertEquals("5.0", expected, actual);

		try {
			actual = convertToRelative(manager, file, true, "TWO");
		} catch (CoreException e) {
			fail("5.4", e);
		}
		expected = new Path("TWO/file.txt");
		assertEquals("6.0", expected, actual);

		try {
			actual = convertToRelative(manager, file, true, "TWO");
		} catch (CoreException e) {
			fail("6.1", e);
		}
		expected = new Path("TWO/file.txt");
		assertEquals("7.0", expected, actual);

		try {
			actual = convertToRelative(manager, file, false, null);
		} catch (CoreException e) {
			fail("7.1", e);
		}
		expected = new Path("TWO/file.txt");
		assertEquals("8.0", expected, actual);

		try {
			manager.setValue("TWO", (IPath) null);
		} catch (CoreException e) {
			fail("8.1", e);
		}

		// now without any direct reference
		try {
			actual = convertToRelative(manager, file, false, null);
		} catch (CoreException e) {
			fail("8.2", e);
		}
		expected = file;
		assertEquals("9.0", expected, actual);

		try {
			actual = convertToRelative(manager, file, true, null);
		} catch (CoreException e) {
			fail("9.1", e);
		}
		expected = new Path("PARENT-1-ONE/other/file.txt");
		assertEquals("10.0", expected, actual);
	}

	/**
	 * Test IPathVariableManager#testValidateName
	 */
	public void testValidateName() {

		// valid names
		assertTrue("0.0", manager.validateName("ECLIPSEHOME").isOK());
		assertTrue("0.1", manager.validateName("ECLIPSE_HOME").isOK());
		assertTrue("0.2", manager.validateName("ECLIPSE_HOME_1").isOK());
		assertTrue("0.3", manager.validateName("_").isOK());

		// invalid names
		assertTrue("1.0", !manager.validateName("1FOO").isOK());
		assertTrue("1.1", !manager.validateName("FOO%BAR").isOK());
		assertTrue("1.2", !manager.validateName("FOO$BAR").isOK());
		assertTrue("1.3", !manager.validateName(" FOO").isOK());
		assertTrue("1.4", !manager.validateName("FOO ").isOK());

	}

	/**
	 * Regression test for Bug 304195
	 */
	public void testEmptyURIResolution() {
		IPath path = new Path(new String());
		URI uri = URIUtil.toURI(path);
		try {
			manager.resolveURI(uri);
		} catch (Throwable e) {
			fail("1.2", e);
		}
		try {
			getWorkspace().getPathVariableManager().resolveURI(uri);
		} catch (Throwable e) {
			fail("1.2", e);
		}
	}

	/**
	 * Test IPathVariableManager#addChangeListener and IPathVariableManager#removeChangeListener
	 */
	public void testListeners() {
		PathVariableChangeVerifier listener = new PathVariableChangeVerifier();
		manager.addChangeListener(listener);
		IPath pathOne = new Path("/blort/foobar");
		//add device if necessary
		pathOne = new Path(pathOne.toFile().getAbsolutePath());
		IPath pathOneEdit = pathOne.append("myworld");

		try {

			// add a variable
			try {
				manager.setValue("one", pathOne);
			} catch (CoreException e) {
				fail("1.0", e);
			}
			listener.addExpectedEvent(IPathVariableChangeEvent.VARIABLE_CREATED, "one", pathOne);
			try {
				listener.verify();
			} catch (PathVariableChangeVerifier.VerificationFailedException e) {
				fail("1.1", e);
			}

			// change a variable
			listener.reset();
			try {
				manager.setValue("one", pathOneEdit);
			} catch (CoreException e) {
				fail("2.0", e);
			}
			listener.addExpectedEvent(IPathVariableChangeEvent.VARIABLE_CHANGED, "one", pathOneEdit);
			try {
				listener.verify();
			} catch (PathVariableChangeVerifier.VerificationFailedException e) {
				fail("2.1", e);
			}

			// remove a variable
			listener.reset();
			try {
				manager.setValue("one", (IPath) null);
			} catch (CoreException e) {
				fail("3.0", e);
			}
			listener.addExpectedEvent(IPathVariableChangeEvent.VARIABLE_DELETED, "one", null);
			try {
				listener.verify();
			} catch (PathVariableChangeVerifier.VerificationFailedException e) {
				fail("3.1", e);
			}

		} finally {
			manager.removeChangeListener(listener);
		}
	}

	boolean contains(Object[] array, Object obj) {
		for (Object element : array) {
			if (element.equals(obj)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Ensure there are no path variables in the workspace.
	 */
	@Override
	protected void tearDown() throws Exception {
		super.tearDown();
		String[] names = manager.getPathVariableNames();
		for (String name : names) {
			manager.setValue(name, (IPath) null);
		}
	}

	@Override
	protected void cleanup() throws CoreException {
		project.delete(true, getMonitor());
		super.cleanup();
	}

	/**
	 * Regression for Bug 308975 - Can't recover from 'invalid' path variable
	 */
	public void testLinkExistInProjectDescriptionButNotInWorkspace() {
		String dorProjectContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + //
				"<projectDescription>" + //
				"<name>ExistingProject</name>" + //
				"<comment></comment>" + //
				"<projects>" + //
				"</projects>" + //
				"<buildSpec>" + //
				"</buildSpec>" + //
				"<natures>" + //
				"</natures>" + //
				"<variableList>" + //
				"<variable>" + //
				"		<name>PROJ_UP</name>" + //
				"		<value>$%7BPARENT-1-PROJECT_LOC%7D</value>" + //
				"	</variable>" + //
				"	</variableList>" + //
				"</projectDescription>";

		IProject existingProject = getWorkspace().getRoot().getProject("ExistingProject");

		ensureExistsInWorkspace(new IResource[] {existingProject}, true);

		try {
			existingProject.close(getMonitor());
			ProjectInfo info = (ProjectInfo) ((Project) existingProject).getResourceInfo(false, false);
			info.clear(ICoreConstants.M_USED);
			String dotProjectPath = existingProject.getLocation().append(".project").toOSString();
			FileWriter fstream = new FileWriter(dotProjectPath);
			BufferedWriter out = new BufferedWriter(fstream);
			out.write(dorProjectContent);
			out.close();
			existingProject.open(getMonitor());
		} catch (CoreException e) {
			fail("1.99", e);
		} catch (IOException e) {
			fail("1.99", e);
		}

		IPathVariableManager pathVariableManager = existingProject.getPathVariableManager();
		String[] varNames = pathVariableManager.getPathVariableNames();

		for (String varName : varNames) {
			try {
				pathVariableManager.getURIValue(varName);
			} catch (Exception e) {
				fail("3.99", e);
			}
		}
	}

	/**
	 * Regression test for Bug 328045 where a class cast exception is thrown when
	 * attempting to get the location of a resource that would live under an
	 * existing IFile.
	 */
	public void testDiscoverLocationOfInvalidFile() {
		IPath filep = new Path("someFile");
		IPath invalidChild = filep.append("invalidChild");

		// Create filep
		IFile f = project.getFile(filep);
		ensureExistsInWorkspace(f, true);

		// Get a reference to a child
		IFile invalidFile = project.getFile(invalidChild);

		// Don't care about the result, just care there's no exception.
		invalidFile.getLocationURI();
	}
}
