/*******************************************************************************
 * Copyright (c) 2011, 2017 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.jdt.debug.tests.sourcelookup;

import java.nio.file.Files;
import java.util.List;

import org.eclipse.core.internal.resources.ResourceException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.sourcelookup.ISourceContainer;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.testplugin.JavaProjectHelper;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.debug.tests.TestUtil;
import org.eclipse.jdt.internal.core.ClassFile;
import org.eclipse.jdt.internal.launching.JavaSourceLookupUtil;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.sourcelookup.containers.PackageFragmentRootSourceContainer;

/**
 * Tests for finding / showing source from jar files from related projects
 */
public class JarSourceLookupTests extends AbstractDebugTest {

	private static final String SAMPLE_JAR_PATH = "/JarProject/lib/sample.jar";
	public static final String A_RUN_JAR = "testJar.RunJar";
	static IJavaProject fgJarProject = null;
	
	String RefPjName = "JarRefProject";
	String fJarProject = "JarProject";
	
	/**
	 * Constructor
	 */
	public JarSourceLookupTests() {
		super("JarSourceLookupTests");
	}
	
	/**
	 * Disposes all source containers after a test, ensures no containers are still holding open Jar references, which can lead to {@link ResourceException}s
	 * when we try to delete / setup following tests
	 * @param containers
	 */
	void disposeContainers(ISourceContainer[] containers) {
		if(containers != null) {
			for (int i = 0; i < containers.length; i++) {
				containers[i].dispose();
			}
		}
	}
	
	@Override
	protected IJavaProject getProjectContext() {
		return fgJarProject;
	}
	
	@Override
	protected void setUp() throws Exception {
		assertWelcomeScreenClosed();
		TestUtil.runEventLoop();
		TestUtil.cleanUp();
		IPath testrpath = new Path("testresources");
		IProject jarProject = createProjectClone(fJarProject, testrpath.append(fJarProject).toString(), true);

		IFile jar = jarProject.getFile("lib/sample.jar");
		assertTrue("lib/sample.jar is missing in project: " + jarProject.getName(), jar.exists());

		fgJarProject = createJavaProjectClone(RefPjName, testrpath.append(RefPjName).toString(), JavaProjectHelper.J2SE_1_4_EE_NAME, true);

		IProject jarRefProject = fgJarProject.getProject();
		IFile cp = jarRefProject.getFile(".classpath");
		assertTrue(".classpath is missing in project: " + jarRefProject.getName(), cp.exists());
		java.nio.file.Path path = cp.getLocation().toFile().toPath();
		List<String> lines = Files.readAllLines(path);
		boolean foundJar = false;
		for (String line : lines) {
			if (line.contains(SAMPLE_JAR_PATH)) {
				foundJar = true;
				break;
			}
		}
		if (!foundJar) {
			fail("The .classpath from project " + jarRefProject + " is unexpected and does not have an entry for " + SAMPLE_JAR_PATH + ": "
					+ new String(Files.readAllBytes(path)));
		}
		waitForBuild();
	}
	
	@Override
	protected void tearDown() throws Exception {
		removeAllBreakpoints();
		if (fgJarProject.exists()) {
			fgJarProject.getProject().delete(true, null);
		}
		TestUtil.cleanUp();
		super.tearDown();
	}
	
	/**
	 * Ensures the translation of source containers yields the correct containers
	 * 
	 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=346116
	 * 
	 * @throws Exception
	 */
	public void testTranslateContainers() throws Exception {
		createLaunchConfiguration(fgJarProject, LAUNCHCONFIGURATIONS, A_RUN_JAR);
		ILaunchConfiguration config = getLaunchConfiguration(fgJarProject, LAUNCHCONFIGURATIONS, A_RUN_JAR);
		IRuntimeClasspathEntry[] entries = JavaRuntime.computeUnresolvedSourceLookupPath(config);
		assertEquals("There should be 2 containers returned (JRE and classpath)", 2, entries.length);
		IRuntimeClasspathEntry[] resolved = JavaRuntime.resolveSourceLookupPath(entries, config);
		ISourceContainer[] containers = JavaSourceLookupUtil.translate(resolved);
		try {
			assertTrue("There must be computed containers", containers.length > 0);
			//the number of containers is M + 2, where M is unknown across JREs, 1 for the project container and 1 for the JAR we are looking for
			assertTrue("There should be at least 2 containers returned", containers.length >= 2);
			for (int i = 0; i < containers.length; i++) {
				ISourceContainer sourceContainer = containers[i];
				if ("sample.jar".equals(sourceContainer.getName()) && sourceContainer instanceof PackageFragmentRootSourceContainer) {
					PackageFragmentRootSourceContainer container = (PackageFragmentRootSourceContainer) sourceContainer;
					if (SAMPLE_JAR_PATH.equals(container.getPackageFragmentRoot().getPath().toString())) {
						return;
					}
				}
			}
			StringBuilder dump = new StringBuilder();
			for (ISourceContainer sc : containers) {
				dump.append(sc.getName());
				if (sc instanceof PackageFragmentRootSourceContainer) {
					PackageFragmentRootSourceContainer pfsc = (PackageFragmentRootSourceContainer) sc;
					dump.append(" with path: ").append(pfsc.getPath());
				}
				dump.append(", ");
			}
			dump.setLength(dump.length() - 2);
			dump.append(".\n Those containers were resolved from: ");
			for (IRuntimeClasspathEntry cpe : resolved) {
				dump.append(cpe);
				dump.append(", ");
			}

			dump.setLength(dump.length() - 2);
			fail("We did not find a source container that was a PackageFragmentRootSourceContainer "
					+ "and had the name " + SAMPLE_JAR_PATH + ", but found source containers: " + dump);
		}
		finally {
			disposeContainers(containers);
		}
	}
	
	/**
	 * Tests that the class file is found as source when the lookup is done from a jar from another project
	 * 
	 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=346116
	 * 
	 * @throws Exception
	 */
	public void testInspectClassFileFromJar() throws Exception {
		createLaunchConfiguration(fgJarProject, LAUNCHCONFIGURATIONS, A_RUN_JAR);
		createLineBreakpoint(16, A_RUN_JAR);
		ILaunchConfiguration config = getLaunchConfiguration(fgJarProject, LAUNCHCONFIGURATIONS, A_RUN_JAR);
		IJavaThread thread = null;
		try {
			 thread = launchToBreakpoint(config);
			 IStackFrame frame = thread.getTopStackFrame();
			 assertTrue("The found frame should be an IJavaStackFrame", frame instanceof IJavaStackFrame);
			 stepInto((IJavaStackFrame)frame);
			 assertNotNull("the stack frame from the thread cannot be null", frame);
			 IValue value = doEval(thread, "this");
			 assertNotNull("The evaluation result cannot be null", value);
			 assertEquals("the name of the type being inspected must be a.JarClass", "a.JarClass", value.getReferenceTypeName());
		}
		finally {
			terminateAndRemove(thread);
		}
	}
	
	/**
	 * Tests that the class file is found as source when the lookup is done from a jar from another project
	 * 
	 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=346116
	 * 
	 * @throws Exception
	 */
	public void testShowClassFileFromJar() throws Exception {
		createLaunchConfiguration(fgJarProject, LAUNCHCONFIGURATIONS, A_RUN_JAR);
		createLineBreakpoint(16, A_RUN_JAR);
		ILaunchConfiguration config = getLaunchConfiguration(fgJarProject, LAUNCHCONFIGURATIONS, A_RUN_JAR);
		IJavaThread thread = null;
		try {
			 thread = launchToBreakpoint(config);
			 IStackFrame frame = thread.getTopStackFrame();
			 assertNotNull("The top stack frame cannot be null", frame);
			 assertTrue("The found frame should be an IJavaStackFrame", frame instanceof IJavaStackFrame);
			 Object source = lookupSource(frame);
			assertNotNull("We should have found source for the main class testJar.RunJar", source);
			 assertTrue("The found source should be an IFile", source instanceof IFile);
			 assertEquals("We should have found a file named RunJar.java", ((IFile)source).getName(), "RunJar.java");
			 
			 stepInto((IJavaStackFrame)frame);
			 frame = thread.getTopStackFrame();
			 assertNotNull("The top stack frame cannot be null", frame);
			 
			 source = lookupSource(frame);
			 assertNotNull("We should have found source for the jar class a.JarClass", source);
			 assertTrue("The found source should be a ClassFile", source instanceof ClassFile);
			 assertEquals("we should have found a file named a.JarClass.class", ((ClassFile)source).getElementName(), "JarClass.class");
		}
		finally {
			terminateAndRemove(thread);
		}
	}
	
	/**
	 * Looks up source for the given frame using its backing {@link ISourceLocator} from its {@link ILaunch}
	 * @param frame the frame to look up source for
	 * @return the source object or <code>null</code>
	 */
	Object lookupSource(IStackFrame frame) {
		ISourceLocator locator = frame.getLaunch().getSourceLocator();
		assertNotNull("The default Java source locator cannot be null", locator);
		return locator.getSourceElement(frame);
	}
}
