/*******************************************************************************
 * Copyright (c) 2010,2011 IBM Corporation
 * 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.ptp.pldt.tests;

import java.util.Arrays;
import java.util.List;

import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.ptp.pldt.common.Artifact;
import org.eclipse.ptp.pldt.common.ArtifactManager;
import org.eclipse.ptp.pldt.common.IArtifact;
import org.eclipse.ptp.pldt.internal.common.IDs;
import org.eclipse.ptp.pldt.openmp.analysis.PAST.PASTOMPPragma;
import org.eclipse.ptp.pldt.openmp.core.actions.RunAnalyseOpenMPcommandHandler;
import org.eclipse.ptp.pldt.openmp.core.internal.OpenMPIDs;

/**
 * @author beth
 * 
 */
public class Test_OpenMP extends PldtBaseTestFramework {

	public void testOpenMPartifacts() throws Exception {
		System.out.println("\n==> " + getMethodName() + "()...");

		IFile file = importFile("resources", "helloOpenMP.c");
		assertNotNull(file);

		IFile openmpInclude = importFile("resources/includes", "omp.h");
		assertNotNull(openmpInclude);
		String tempPath = openmpInclude.getFullPath().toOSString();// includePath= /RegressionTestProject/mpi.h
		// System.out.println("tempPath="+tempPath);
		String includePath = openmpInclude.getWorkspace().getRoot().getRawLocation().toOSString()
				+ openmpInclude.getFullPath().toFile().getAbsolutePath();
		// System.out.println("includePath= "+includePath);

		assertTrue(file instanceof IAdaptable);

		CoreModel.getDefault().getCModel().makeConsistent(new NullProgressMonitor());// jeff

		assertNotNull(cproject);
		ICElement ce = cproject.findElement(file.getFullPath());

		// ICElement covers folders and translationunits
		// final ICElement ce = (ICElement) ((IAdaptable)file).getAdapter(ICElement.class);
		assertNotNull(ce);
		List<String> includes = Arrays.asList(new String[] { includePath });
		RunAnalyseOpenMPcommandHandler racm = new RunAnalyseOpenMPcommandHandler();

		racm.runResource(new NullProgressMonitor(), ce, 0, includes);

		IMarker[] markers = file.findMarkers(OpenMPIDs.MARKER_ID, true, IResource.DEPTH_INFINITE);
		assertNotNull(markers);
		System.out.println("numMarkers: " + markers.length);
		// need to sort markers, since they are not returned in a pre-determined order??

		for (int i = 0; i < markers.length; i++) {
			IMarker marker = markers[i];
			int lineNo = (Integer) marker.getAttribute(IMarker.LINE_NUMBER);
			System.out.println(i + " marker: lineNo " + lineNo + " name: " + marker.getAttribute(IDs.NAME));
		}

		// When strings don't match, click on the first entry (ComparisonFailure) in the Failure Trace in the JUnit view to get a
		// diff view
		// assertEquals("This\nis\na\ntest", "This\nwas\na\ntest");
		// there really should be three, including a pragma. testOpenMP_pragmas will
		// concentrate on these
		int[] expectedLinenos = { 12, 14, 20 };
		final String pragma = "#pragma omp parallel private(numThreads, tid)";
		String[] expectedOpenMPTypes = { pragma, "omp_get_thread_num", "omp_get_num_threads" };
		ArtifactWithLine[] expectedArts = new ArtifactWithLine[expectedLinenos.length];
		ArtifactWithLine[] markerArts = new ArtifactWithLine[markers.length];
		for (int i = 0; i < expectedArts.length; i++) {
			expectedArts[i] = new ArtifactWithLine(expectedLinenos[i], expectedOpenMPTypes[i]);
		}
		for (int i = 0; i < markerArts.length; i++) {
			markerArts[i] = new ArtifactWithLine(markers[i]);
		}
		Arrays.sort(expectedArts);
		Arrays.sort(markerArts);

		assertEquals(expectedArts.length, markerArts.length);
		// Since these tests are in a loop, if one fails, must inspect the Console output to know which ones finished and which one
		// failed.
		for (int i = 0; i < markers.length; i++) {
			// Marker should be on the line number we expect
			System.out.println(i + ". " + expectedArts[i].getLineNo() + " = " + markerArts[i].getLineNo());
			assertEquals(expectedArts[i].getLineNo(), markerArts[i].getLineNo());

			// Marker should be of the type name we expect
			System.out.println("    " + expectedArts[i].getName() + " = " + markerArts[i].getName());
			assertEquals(expectedArts[i].getName(), markerArts[i].getName());

			boolean test = markerArts[i].equals(expectedArts[i]);
			System.out.println("   markerArts.equals expectedArts: " + test);
			// the following never works, so we'll be happy enough with the two assertEquals above.
			// assertEquals(expectedArts[i], markerArts[i]);

		}

	}

	public void testOpenMP_pragmas() throws Exception {
		System.out.println("\n==> " + getMethodName() + "()...");

		IFile file = importFile("resources", "helloOpenMPpragmas.c");
		assertNotNull(file);

		IFile openmpInclude = importFile("resources/includes", "omp.h");
		assertNotNull(openmpInclude);
		String tempPath = openmpInclude.getFullPath().toOSString();// includePath= /RegressionTestProject/mpi.h
		// System.out.println("tempPath="+tempPath);
		String includePath = openmpInclude.getWorkspace().getRoot().getRawLocation().toOSString()
				+ openmpInclude.getFullPath().toFile().getAbsolutePath();
		// System.out.println("includePath= "+includePath);

		assertTrue(file instanceof IAdaptable);

		CoreModel.getDefault().getCModel().makeConsistent(new NullProgressMonitor());// jeff

		assertNotNull(cproject);
		ICElement ce = cproject.findElement(file.getFullPath());

		// ICElement covers folders and translationunits
		// final ICElement ce = (ICElement) ((IAdaptable)file).getAdapter(ICElement.class);
		assertNotNull(ce);
		List<String> includes = Arrays.asList(new String[] { includePath });
		RunAnalyseOpenMPcommandHandler racm = new RunAnalyseOpenMPcommandHandler();

		racm.runResource(new NullProgressMonitor(), ce, 0, includes);

		IMarker[] markers = file.findMarkers(OpenMPIDs.MARKER_ID, true, IResource.DEPTH_INFINITE);
		assertNotNull(markers);
		System.out.println("numMarkers: " + markers.length);
		// need to sort markers, since they are not returned in a pre-determined order??

		// When strings don't match, click on the first entry (ComparisonFailure) in the Failure Trace in the JUnit view to get a
		// diff view
		// assertEquals("This\nis\na\ntest", "This\nwas\na\ntest");

		int[] expectedLinenos = { 21, 23, 29, 34, 36, 40 };
		final String prag = "#pragma omp parallel private(numThreads, tid)";
		final String prag2 = "#pragma omp parallel shared(n,a,b)";
		final String pragFor = "#pragma omp for";
		final String pragParFor = "#pragma omp parallel for";
		String[] expectedMpiTypes = { prag, "omp_get_thread_num", "omp_get_num_threads", prag2, pragFor, pragParFor };
		ArtifactWithLine[] expectedArts = new ArtifactWithLine[expectedLinenos.length];
		ArtifactWithLine[] markerArts = new ArtifactWithLine[markers.length];
		for (int i = 0; i < expectedArts.length; i++) {
			expectedArts[i] = new ArtifactWithLine(expectedLinenos[i], expectedMpiTypes[i]);
		}
		for (int i = 0; i < markerArts.length; i++) {
			markerArts[i] = new ArtifactWithLine(markers[i]);
		}
		Arrays.sort(expectedArts);
		Arrays.sort(markerArts);
		for (int i = 0; i < markers.length; i++) {
			IMarker marker = markers[i];
			int lineNo = (Integer) marker.getAttribute(IMarker.LINE_NUMBER);
			System.out.println(i + " marker: lineNo " + lineNo + " name: " + marker.getAttribute(IDs.NAME));
		}

		// should find pragma and two other openmp artifacts
		assertEquals(expectedArts.length, markerArts.length);
		// Since these tests are in a loop, if one fails, must inspect the Console output to know which ones finished and which one
		// failed.
		for (int i = 0; i < markers.length; i++) {
			// Marker should be on the line number we expect
			System.out.println(i + ". " + expectedArts[i].getLineNo() + " = " + markerArts[i].getLineNo());
			assertEquals(expectedArts[i].getLineNo(), markerArts[i].getLineNo());

			// Marker should be of the type name we expect
			System.out.println("    " + expectedArts[i].getName() + " = " + markerArts[i].getName());
			assertEquals(expectedArts[i].getName(), markerArts[i].getName());

			boolean test = markerArts[i].equals(expectedArts[i]);
			// the following never works, so we'll be happy enough with the two assertEquals above.
			// assertEquals(expectedArts[i], markerArts[i]);

		}
		System.out.println("== Check regions for 'show pragma region' usage");
		// check information needed for pragma show region action
		RegionInfo ri0 = getRegion(ArtifactManager.getArtifact(markerArts[0].getMarker()));
		assertNotNull(ri0);
		System.out.println("0. region offset:" + ri0.offset + " length:" + ri0.length + "  " + markerArts[0].getName());
		assertEquals(642, ri0.offset);
		assertEquals(290, ri0.length);

		RegionInfo ri1 = getRegion(ArtifactManager.getArtifact(markerArts[1].getMarker()));
		assertNull(ri1);
		// System.out.println("1. region offset:"+ri1.offset+ " length:"+ri1.length);
		System.out.println("1. not a pragma    " + markerArts[1].getName());

		RegionInfo ri2 = getRegion(ArtifactManager.getArtifact(markerArts[2].getMarker()));
		assertNull(ri2);
		System.out.println("2. not a pragma    " + markerArts[2].getName());
		// assertEquals(642,ri0.offset);
		// assertEquals(290, ri0.length);

		RegionInfo ri3 = getRegion(ArtifactManager.getArtifact(markerArts[3].getMarker()));
		assertNotNull(ri3);
		System.out.println("3. region offset:" + ri3.offset + " length:" + ri3.length + "  " + markerArts[3].getName());
		assertEquals(1014, ri3.offset);
		assertEquals(214, ri3.length);

		RegionInfo ri4 = getRegion(ArtifactManager.getArtifact(markerArts[4].getMarker()));
		assertNotNull(ri4);
		System.out.println("4. region offset:" + ri4.offset + " length:" + ri4.length + "  " + markerArts[4].getName());
		assertEquals(1038, ri4.offset);
		assertEquals(187, ri4.length);

		RegionInfo ri5 = getRegion(ArtifactManager.getArtifact(markerArts[5].getMarker()));
		assertNotNull(ri5);
		System.out.println("5. region offset:" + ri5.offset + " length:" + ri5.length + "  " + markerArts[5].getName());
		assertEquals(1170, ri5.offset);
		assertEquals(50, ri5.length);

		System.out.println("done");

	}

	/**
	 * copied from OpenMPArtifactView.makeShowInfoAction() more or less - not ideal
	 * 
	 * @param a
	 */
	RegionInfo getRegion(IArtifact a) {
		Artifact artifact = (Artifact) a;
		Object p = artifact.getArtifactAssist();
		if (p == null || !(p instanceof PASTOMPPragma))
			return null;
		;
		PASTOMPPragma ompPragma = (PASTOMPPragma) p;
		IASTNode iRegion = ompPragma.getRegion();
		ASTNode region = (iRegion instanceof ASTNode ? (ASTNode) iRegion : null);
		if (region == null)
			return null;
		int offset = ompPragma.getRegionOffset();
		int length = ompPragma.getRegionLength();
		RegionInfo ri = new RegionInfo(offset, length);
		return ri;

	}

	protected class RegionInfo {
		int offset;
		int length;

		RegionInfo(int offset, int length) {
			this.offset = offset;
			this.length = length;
		}
	}

}
