/*******************************************************************************
 * Copyright (c) 2000, 2005 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.core.tests.performance;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;

import junit.framework.Test;

import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.SourceElementParser;
import org.eclipse.jdt.internal.compiler.SourceElementRequestorAdapter;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.parser.Scanner;
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.compiler.util.Util;
import org.eclipse.test.performance.Performance;

/**
 * Class to test compiler performance.
 * This includes tests on build, batch compiler, Scanner and Parser.
 */
public class FullSourceWorkspaceBuildTests extends FullSourceWorkspaceTests {
	
	// Tests counters
	private static int TESTS_COUNT = 0;
	private final static int ITERATIONS_COUNT = 10;
	private final static int SCAN_REPEAT = 800; // 800 is default

	// Tests thresholds
	private final static int TIME_THRESHOLD = 150;
	
	// Log files
	private static PrintStream[] LOG_STREAMS = new PrintStream[LOG_TYPES.length];

	
	/**
	 * @param name
	 */
	public FullSourceWorkspaceBuildTests(String name) {
		super(name);
	}

	static {
//		TESTS_PREFIX = "testPerfBatch";
//		TESTS_NAMES = new String[] { "testFullBuildAllWarning" };
	}

	public static Test suite() {
		Test suite = buildSuite(testClass());
		TESTS_COUNT = suite.countTestCases();
		createPrintStream(testClass().getName(), LOG_STREAMS, TESTS_COUNT, null);
		return suite;
	}

	private static Class testClass() {
		return FullSourceWorkspaceBuildTests.class;
	}

	/*
	 * Parse several times a file giving its name.
	 */
	private long[] parseFile(String fileName, int kind, int iterations) throws InvalidInputException, IOException {

		// Test for parser
		File file = new File(fileName);
		char[] content = Util.getFileCharContent(file, null);
		CompilerOptions options = new CompilerOptions();
		options.sourceLevel = ClassFileConstants.JDK1_4;
		options.targetJDK = ClassFileConstants.JDK1_4;
		ProblemReporter problemReporter = 
				new ProblemReporter(
					DefaultErrorHandlingPolicies.exitAfterAllProblems(), 
					options, 
					new DefaultProblemFactory());
		
		// Create parser
        Parser parser = null;
		switch (kind) {
		case 1: // SourceElementParser
				parser = new SourceElementParser(new SourceElementRequestorAdapter(), problemReporter.problemFactory, options, true, true);
				break;
			default:
				parser = new Parser(problemReporter, true);
				break;
		}

		// Warm up
		for (int i = 0; i < 2; i++) {
			ICompilationUnit unit = new CompilationUnit(content, file.getName(), null);
			CompilationResult unitResult = new CompilationResult(unit, 0, 1, options.maxProblemsPerUnit);				
			CompilationUnitDeclaration unitDeclaration = parser.dietParse(unit, unitResult);
			parser.getMethodBodies(unitDeclaration);
		}

		// Clean memory
		runGc();

		// Measures
		long parsedLines = 0;
		long parsedCharacters = 0;
		long start = 0;
		if (DEBUG) {
			start = System.currentTimeMillis();
		}
		startMeasuring();
		for (int i = 0; i < iterations; i++) {
			ICompilationUnit unit = new CompilationUnit(content, file.getName(), null);
			CompilationResult unitResult = new CompilationResult(unit, 0, 1, options.maxProblemsPerUnit);				
			CompilationUnitDeclaration unitDeclaration = parser.dietParse(unit, unitResult);
			parser.getMethodBodies(unitDeclaration);
			parsedCharacters += content.length;
			parsedLines += unitResult.lineSeparatorPositions.length;
		}
		stopMeasuring();

		// Warn if measure time is not enough while debugging
		if (DEBUG) {
			long time = System.currentTimeMillis() - start;
			if (time < TIME_THRESHOLD) {
	            System.err.println(parsedLines + " lines/"+ parsedCharacters + " characters parsed");
			} else {
	            System.out.println(parsedLines + " lines/"+ parsedCharacters + " characters parsed");
			}
		}

		// Return stats
		return new long[] { parsedCharacters, parsedLines };
	}

	/*
	 * Test performance for a parser on one file.
	 * Parse is executed many times ({@link #ITERATIONS_COUNT}) to have significant time for execution.
	 * This test is repeated several times ({@link #MEASURES_COUNT}) to average time measuring.
	 *  
	 * @throws InvalidInputException
	 * @throws IOException
	 */
	void parseParserFile(int kind) throws InvalidInputException, IOException {

		// Get workspace path
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		final IWorkspaceRoot workspaceRoot = workspace.getRoot();
		final String targetWorkspacePath = workspaceRoot.getProject(JavaCore.PLUGIN_ID)
			.getLocation()
			.toFile()
			.getCanonicalPath();
		
		// Run test
		for (int i=0; i<MEASURES_COUNT; i++) {
			parseFile(targetWorkspacePath+"/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java", kind, ITERATIONS_COUNT*6);
		}

		// dump measure
		commitMeasurements();
		assertPerformance();
	}

	/*
	 * Scan a file giving its name.
	 * Two kind of scan is currently possible:
	 * 	- 0: only scan all tokens
	 * 	- 1: scan all tokens and get each identifier
	 */
	private void scanFile(String fileName, int kind) throws InvalidInputException, IOException {

		// Test for scanner
		long tokenCount = 0;
		char[] content = Util.getFileCharContent(new File(fileName),
			null);
		Scanner scanner = new Scanner();
		scanner.setSource(content);

		// Warm up
		for (int i = 0; i < 2; i++) {
			scanner.resetTo(0, content.length);
			tokenize: while (true) {
				int token = scanner.getNextToken();
				switch (kind) {
					case 0: // first case: only read tokens
						switch (token) {
							case TerminalTokens.TokenNameEOF:
								break tokenize;
						}
						break;
					case 1: // second case: read tokens + get ids
						switch (token) {
							case TerminalTokens.TokenNameEOF:
								break tokenize;
							case TerminalTokens.TokenNameIdentifier:
								scanner.getCurrentIdentifierSource();
								break;
						}
						break;
				}
			}
		}

		// Clean memory
		runGc();

		// Measures
		long size = 0;
		for (int i = 0; i < MEASURES_COUNT; i++) {
			startMeasuring();
			for (int j = 0; j < SCAN_REPEAT; j++) {
				scanner.resetTo(0, content.length);
				tokenize: while (true) {
					int token = scanner.getNextToken();
					switch (kind) {
						case 0: // first case: only read tokens
							switch (token) {
								case TerminalTokens.TokenNameEOF:
									break tokenize;
							}
							break;
						case 1: // second case: read tokens + get ids
							switch (token) {
								case TerminalTokens.TokenNameEOF:
									break tokenize;
								case TerminalTokens.TokenNameIdentifier:
									char[] c = scanner.getCurrentIdentifierSource();
									size += c.length;
									break;
							}
							break;
					}
					tokenCount++;
				}
			}
			stopMeasuring();
		}

		// Commit
		commitMeasurements();
		assertPerformance();

		// Debug
		if (DEBUG) {
			switch (kind) {
				case 0:
					System.out.println(tokenCount + " tokens read.");
					break;
				case 1:
					System.out.print(tokenCount + " tokens were read ("+size+" characters)");
					break;
			}
		}
	}


	/* (non-Javadoc)
	 * @see junit.framework.TestCase#tearDown()
	 */
	protected void tearDown() throws Exception {

		// End of execution => one test less
		TESTS_COUNT--;

		// Log perf result
		if (LOG_DIR != null) {
			logPerfResult(LOG_STREAMS, TESTS_COUNT);
		}
		
		// Call super at the end as it close print streams
		super.tearDown();
	}

	/**
	 * Full build with no warning.
	 * 
	 * Not calling tagAsSummary means that this test is currently evaluated
	 * before put it in builds performance results.
	 * 
	 * @throws CoreException
	 * @throws IOException
	 */
	public void testFullBuildNoWarning() throws CoreException, IOException {
		tagAsSummary("Compile>Build>Clean>Full>No warning", false); // do NOT put in fingerprint
		setComment(Performance.EXPLAINS_DEGRADATION_COMMENT, "J2SE 5.0 support");
		startBuild(warningOptions(-1/*no warning*/), false);
	}

	/**
	 * Full build with JavaCore default options.
	 * 
	 * @throws CoreException
	 * @throws IOException
	 */
	public void testFullBuildDefault() throws CoreException, IOException {
		tagAsGlobalSummary("Compile>Build>Clean>Full>Default warnings", true); // put in fingerprint
		setComment(Performance.EXPLAINS_DEGRADATION_COMMENT, "J2SE 5.0 support + additional warnings (e.g. validate unused local and private members)");
		startBuild(warningOptions(0/*default warnings*/), false);
	}

	/**
	 * Full build with all warnings.
	 * 
	 * Not calling tagAsSummary means that this test is currently evaluated
	 * before put it in builds performance results.
	 * 
	 * @throws CoreException
	 * @throws IOException
	 * 
	 */
	public void testFullBuildAllWarnings() throws CoreException, IOException {
		tagAsSummary("Compile>Build>Clean>Full>All warnings", false); // do NOT put in fingerprint
		setComment(Performance.EXPLAINS_DEGRADATION_COMMENT, "J2SE 5.0 support");
		startBuild(warningOptions(1/*all warnings*/), false);
	}

	/**
	 * Batch compiler build with no warning
	 * 
	 * Not calling tagAsSummary means that this test is currently evaluated
	 * before put it in builds performance results.
	 * 
	 * @throws IOException
	 */
	public void testBatchCompilerNoWarning() throws IOException {
		tagAsSummary("Compile>Batch>Compiler>No warning", true); // put in fingerprint
		setComment(Performance.EXPLAINS_DEGRADATION_COMMENT, "J2SE 5.0 support");
		buildUsingBatchCompiler("-nowarn");
	}

	/**
	 * Batch compiler build with default warnings
	 * 
	 * Not calling tagAsSummary means that this test is currently evaluated
	 * before put it in builds performance results.
	 * 
	 * @throws IOException
	 */
	public void testBatchCompilerDefault() throws IOException {
		tagAsSummary("Compile>Batch>Compiler>Default warnings", false); // do NOT put in fingerprint
		setComment(Performance.EXPLAINS_DEGRADATION_COMMENT, "J2SE 5.0 support");
		buildUsingBatchCompiler("");
	}

	/**
	 * Batch compiler build with default javadoc warnings
	 * 
	 * Not calling tagAsSummary means that this test is currently evaluated
	 * before put it in builds performance results.
	 * 
	 * @throws IOException
	 */
	public void testBatchCompilerJavadoc() throws IOException {
		tagAsSummary("Compile>Batch>Compiler>Javadoc warnings", false); // do NOT put in fingerprint
		setComment(Performance.EXPLAINS_DEGRADATION_COMMENT, "J2SE 5.0 support");
		buildUsingBatchCompiler("-warn:javadoc");
	}

	/**
	 * Batch compiler build with invalid javadoc warnings
	 * 
	 * Not calling tagAsSummary means that this test is currently evaluated
	 * before put it in builds performance results.
	 * 
	 * @throws IOException
	 */
	// TODO (frederic) put back after having understood why this test result can have variation over 20%
	public void _testBatchCompilerAllJavadoc() throws IOException {
		tagAsSummary("Compile>Batch>Compiler>All Javadoc warnings", false); // do NOT put in fingerprint
		setComment(Performance.EXPLAINS_DEGRADATION_COMMENT, "J2SE 5.0 support");
		buildUsingBatchCompiler("-warn:allJavadoc");
	}

	/**
	 * Batch compiler build with all warnings
	 * 
	 * Not calling tagAsSummary means that this test is currently evaluated
	 * before put it in builds performance results.
	 * 
	 * @throws IOException
	 */
	public void testBatchCompilerAllWarnings() throws IOException {
		tagAsSummary("Compile>Batch>Compiler>All warnings", false); // do NOT put in fingerprint

		String allOptions = "-warn:" +
			"allDeprecation," +
			"allJavadoc," +
			"assertIdentifier," +
			"charConcat," +
			"conditionAssign," +
			"constructorName," +
			"deprecation," +
			"emptyBlock," +
			"fieldHiding," +
			"finally," +
			"indirectStatic," +
			"intfNonInherited," +
			"localHiding," +
			"maskedCatchBlock," +
			"nls," +
			"noEffectAssign," +
			"pkgDefaultMethod," +
			"semicolon," +
			"unqualifiedField," +
			"unusedArgument," +
			"unusedImport," +
			"unusedLocal," +
			"unusedPrivate," +
			"unusedThrown," +
			"unnecessaryElse," +
			"uselessTypeCheck," +
			"specialParamHiding," +
			"staticReceiver," +
			"syntheticAccess," +
			"tasks(TODO|FIX|XXX)";
		setComment(Performance.EXPLAINS_DEGRADATION_COMMENT, "J2SE 5.0 support");
		buildUsingBatchCompiler(allOptions);
	}

	/**
	 * Test performance for Scanner on one file.
	 * Scan is executed many times ({@link #SCAN_REPEAT}) to have significant time for execution.
	 * This test is repeated several times ({@link #ITERATIONS_COUNT}) to average time measuring.
	 *  
	 * @throws InvalidInputException
	 * @throws IOException
	 */
	public void testScanner() throws InvalidInputException, IOException {
		// Do no longer print result in performance fingerprint
		tagAsSummary("Compile>Scan>Parser>Default", true); // put in fingerprint

		// Get workspace path
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		final IWorkspaceRoot workspaceRoot = workspace.getRoot();
		final String targetWorkspacePath = workspaceRoot.getProject(JavaCore.PLUGIN_ID)
			.getLocation()
			.toFile()
			.getCanonicalPath();
		
		// Run test
//		scanFile(targetWorkspacePath+"/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java", 0/*only scan tokens*/);
		scanFile(targetWorkspacePath+"/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java", 1/*scan tokens+get identifiers*/);
	}

	/**
	 * Test performance for Parser on one file.
	 * Parse is executed many times ({@link #ITERATIONS_COUNT}) to have significant time for execution.
	 * This test is repeated several times ({@link #MEASURES_COUNT}) to average time measuring.
	 *  
	 * @throws InvalidInputException
	 * @throws IOException
	 */
	public void testParser() throws InvalidInputException, IOException {
		tagAsSummary("Compile>Parse>Parser>Default", true); // put in fingerprint
		parseParserFile(0); // Parser kind
	}

	/**
	 * Test performance for SourceElementParser on one file.
	 * Parse is executed many times ({@link #ITERATIONS_COUNT}) to have significant time for execution.
	 * This test is repeated several times ({@link #MEASURES_COUNT}) to average time measuring.
	 * 
	 * Note: This test has been temporarily removed as there's unexplicable difference between
	 * HEAD and 3.0 versions for CPU Time results (10% faster) and Elapsed process (25% slower)...
	 * TODO (frederic) Put back when platform-releng will have stabilized performance results process.
	 *  
	 * @throws InvalidInputException
	 * @throws IOException
	 */
	public void _testSourceParser() throws InvalidInputException, IOException {
		tagAsSummary("Compile>SrcParse>Parser>Default", true); // put in fingerprint
		parseParserFile(1); // SourceElementParser kind
	}
}
