/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *     Fraunhofer FIRST - extended API and implementation
 *     Technical University Berlin - extended API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler;

/**
 * OTDT changes:
 * What: role file support (roleFileDepth, binaryMemberNames)
 *
 * What: roll back support using CheckPoint.
 *
 * What: support suppressing decapsulation warnings without entering the problem.
 * Why:  location for suppressing (@SuppressWarnings()) and recording (the type?)
 *       may be different, thus cannot filter during reporting.
 *
 *
 * A compilation result consists of all information returned by the compiler for
 * a single compiled compilation source unit.  This includes:
 * <ul>
 * <li> the compilation unit that was compiled
 * <li> for each type produced by compiling the compilation unit, its binary and optionally its principal structure
 * <li> any problems (errors or warnings) produced
 * <li> dependency info
 * </ul>
 *
 * The principle structure and binary may be null if the compiler could not produce them.
 * If neither could be produced, there is no corresponding entry for the type.
 *
 * The dependency info includes type references such as supertypes, field types, method
 * parameter and return types, local variable types, types of intermediate expressions, etc.
 * It also includes the namespaces (packages) in which names were looked up.
 * It does <em>not</em> include finer grained dependencies such as information about
 * specific fields and methods which were referenced, but does contain their
 * declaring types and any other types used to locate such fields or methods.
 */
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblem;
import org.eclipse.jdt.internal.compiler.util.Util;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class CompilationResult {

	public CategorizedProblem problems[];
	public CategorizedProblem tasks[];
	public int problemCount;
	public int taskCount;
	public ICompilationUnit compilationUnit;
	private Map<CategorizedProblem, ReferenceContext> problemsMap;
	private Set firstErrors;
	private int maxProblemPerUnit;
	public char[][][] qualifiedReferences;
	public char[][] simpleNameReferences;
	public char[][] rootReferences;
	public boolean hasAnnotations = false;
	public boolean hasFunctionalTypes = false;
	public int lineSeparatorPositions[];
	public RecoveryScannerData recoveryScannerData;
	public Map compiledTypes = new Hashtable(11);
	public int unitIndex, totalUnitsKnown;
	public boolean hasBeenAccepted = false;
	public char[] fileName;
	public boolean hasInconsistentToplevelHierarchies = false; // record the fact some toplevel types have inconsistent hierarchies
	public boolean hasSyntaxError = false;
	public char[][] packageName;
	public boolean checkSecondaryTypes = false; // check for secondary types which were created after the initial buildTypeBindings call
	private int numberOfErrors;
	private boolean hasMandatoryErrors;

//{ObjectTeams: separate handling of teams and their roles:
	/** mark the end of real source when adding synthetic positions for SMAP support */
	public int sourceEndPos = Integer.MAX_VALUE;
	// ROFI mark role files:
	public int roleFileDepth = 0;
	public String stripTeamPackagesFromPath(String packagePathName) {
		for (int i=0; i < this.roleFileDepth; i++) {
			int index = packagePathName.lastIndexOf(File.separatorChar);
			if (index > 0) {
				packagePathName = packagePathName.substring(0, index);
			} else {
				return ".";  //$NON-NLS-1$
			}
		}
		return packagePathName;
	}
	public IPath stripTeamPackagesFromPath(IPath packagePath) {
		return packagePath.removeLastSegments(this.roleFileDepth);
	}
	// remember which binary types have been added to the source type,
	// in order not to delete the class file which is still needed!
	private ArrayList<char[]> binaryMemberNames = null;
	public void recordBinaryMemberType(char[] typeName) {
		if (this.binaryMemberNames == null) {
			this.binaryMemberNames = new ArrayList<char[]>();
		}
		this.binaryMemberNames.add(typeName);
	}
	public boolean hasBinaryMember(char[] typeName) {
		if (this.binaryMemberNames == null)
			return false;
		for (Iterator iter = this.binaryMemberNames.iterator(); iter.hasNext();) {
			char[] current = (char[]) iter.next();
			if (CharOperation.equals(current, typeName))
				return true;
		}
		return false;
	}
// SH}

	private static final int[] EMPTY_LINE_ENDS = Util.EMPTY_INT_ARRAY;
	private static final Comparator PROBLEM_COMPARATOR = new Comparator() {
		@Override
		public int compare(Object o1, Object o2) {
			return ((CategorizedProblem) o1).getSourceStart() - ((CategorizedProblem) o2).getSourceStart();
		}
	};

public CompilationResult(char[] fileName, int unitIndex, int totalUnitsKnown, int maxProblemPerUnit){
	this.fileName = fileName;
	this.unitIndex = unitIndex;
	this.totalUnitsKnown = totalUnitsKnown;
	this.maxProblemPerUnit = maxProblemPerUnit;
}

public CompilationResult(ICompilationUnit compilationUnit, int unitIndex, int totalUnitsKnown, int maxProblemPerUnit){
	this.fileName = compilationUnit.getFileName();
	this.compilationUnit = compilationUnit;
	this.unitIndex = unitIndex;
	this.totalUnitsKnown = totalUnitsKnown;
	this.maxProblemPerUnit = maxProblemPerUnit;
}
//{ObjectTeams: support checkpointing and roll-back:
public static class CheckPoint {
	CategorizedProblem[] problems;
	int count;
	int numberOfErrors;
	ReferenceContext context;
	boolean ignoreFurtherInvestigation;
}
public @NonNull CheckPoint getCheckPoint(ReferenceContext referenceContext) {
	CheckPoint result = new CheckPoint();
	if (this.problems != null) {
		int len = this.problems.length;
		System.arraycopy(this.problems, 0,
						 result.problems= new CategorizedProblem[len], 0,
						 len);
	}
	result.count   		  = this.problemCount;
	result.numberOfErrors = this.numberOfErrors;
	result.context		  = referenceContext;
	result.ignoreFurtherInvestigation = referenceContext.hasErrors();
	return result;
}
public void rollBack(CheckPoint cp) {
	for (int i = cp.count; i < this.problemCount; i++) {
		this.problemsMap.remove(this.problems[i]);
	}
	this.problems       = cp.problems;
	this.problemCount   = cp.count;
	this.numberOfErrors = cp.numberOfErrors;
	if (!cp.ignoreFurtherInvestigation)
		cp.context.resetErrorFlag();
}
// SH}

private int computePriority(CategorizedProblem problem){
	final int P_STATIC = 10000;
	final int P_OUTSIDE_METHOD = 40000;
	final int P_FIRST_ERROR = 20000;
	final int P_ERROR = 100000;

	int priority = 10000 - problem.getSourceLineNumber(); // early problems first
	if (priority < 0) priority = 0;
	if (problem.isError()){
		priority += P_ERROR;
	}
	ReferenceContext context = this.problemsMap == null ? null : this.problemsMap.get(problem);
	if (context != null){
		if (context instanceof AbstractMethodDeclaration){
			AbstractMethodDeclaration method = (AbstractMethodDeclaration) context;
			if (method.isStatic()) {
				priority += P_STATIC;
			}
		} else {
			priority += P_OUTSIDE_METHOD;
		}
		if (this.firstErrors.contains(problem)){ // if context is null, firstErrors is null too
		  priority += P_FIRST_ERROR;
	    }
	} else {
		priority += P_OUTSIDE_METHOD;
	}
	return priority;
}

public CategorizedProblem[] getAllProblems() {
	CategorizedProblem[] onlyProblems = getProblems();
	int onlyProblemCount = onlyProblems != null ? onlyProblems.length : 0;
	CategorizedProblem[] onlyTasks = getTasks();
	int onlyTaskCount = onlyTasks != null ? onlyTasks.length : 0;
	if (onlyTaskCount == 0) {
		return onlyProblems;
	}
	if (onlyProblemCount == 0) {
		return onlyTasks;
	}
	int totalNumberOfProblem = onlyProblemCount + onlyTaskCount;
	CategorizedProblem[] allProblems = new CategorizedProblem[totalNumberOfProblem];
	int allProblemIndex = 0;
	int taskIndex = 0;
	int problemIndex = 0;
	while (taskIndex + problemIndex < totalNumberOfProblem) {
		CategorizedProblem nextTask = null;
		CategorizedProblem nextProblem = null;
		if (taskIndex < onlyTaskCount) {
			nextTask = onlyTasks[taskIndex];
		}
		if (problemIndex < onlyProblemCount) {
			nextProblem = onlyProblems[problemIndex];
		}
		// select the next problem
		CategorizedProblem currentProblem = null;
		if (nextProblem != null) {
			if (nextTask != null) {
				if (nextProblem.getSourceStart() < nextTask.getSourceStart()) {
					currentProblem = nextProblem;
					problemIndex++;
				} else {
					currentProblem = nextTask;
					taskIndex++;
				}
			} else {
				currentProblem = nextProblem;
				problemIndex++;
			}
		} else {
			if (nextTask != null) {
				currentProblem = nextTask;
				taskIndex++;
			}
		}
		allProblems[allProblemIndex++] = currentProblem;
	}
	return allProblems;
}

public ClassFile[] getClassFiles() {
	ClassFile[] classFiles = new ClassFile[this.compiledTypes.size()];
	this.compiledTypes.values().toArray(classFiles);
	return classFiles;
}

/**
 * Answer the initial compilation unit corresponding to the present compilation result
 */
public ICompilationUnit getCompilationUnit(){
	return this.compilationUnit;
}

/**
 * Answer the errors encountered during compilation.
 */
public CategorizedProblem[] getErrors() {
	CategorizedProblem[] reportedProblems = getProblems();
	int errorCount = 0;
	for (int i = 0; i < this.problemCount; i++) {
		if (reportedProblems[i].isError()) errorCount++;
	}
	if (errorCount == this.problemCount) return reportedProblems;
	CategorizedProblem[] errors = new CategorizedProblem[errorCount];
	int index = 0;
	for (int i = 0; i < this.problemCount; i++) {
		if (reportedProblems[i].isError()) errors[index++] = reportedProblems[i];
	}
	return errors;
}


/**
 * Answer the initial file name
 */
public char[] getFileName(){
	return this.fileName;
}

public int[] getLineSeparatorPositions() {
	return this.lineSeparatorPositions == null ? CompilationResult.EMPTY_LINE_ENDS : this.lineSeparatorPositions;
}

/**
 * Answer the problems (errors and warnings) encountered during compilation.
 *
 * This is not a compiler internal API - it has side-effects !
 * It is intended to be used only once all problems have been detected,
 * and makes sure the problems slot as the exact size of the number of
 * problems.
 */
public CategorizedProblem[] getProblems() {
	// Re-adjust the size of the problems if necessary.
	if (this.problems != null) {
		if (this.problemCount != this.problems.length) {
			System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount]), 0, this.problemCount);
		}

		if (this.maxProblemPerUnit > 0 && this.problemCount > this.maxProblemPerUnit){
			quickPrioritize(this.problems, 0, this.problemCount - 1);
			this.problemCount = this.maxProblemPerUnit;
			System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount]), 0, this.problemCount);
		}

		// Stable sort problems per source positions.
		Arrays.sort(this.problems, 0, this.problems.length, CompilationResult.PROBLEM_COMPARATOR);
		//quickSort(problems, 0, problems.length-1);
	}
//{ObjectTeams: safer:
	else
		return new CategorizedProblem[0];
// SH}
	return this.problems;
}
/**
 * Same as getProblems() but don't answer problems that actually concern the enclosing package.
 */
public CategorizedProblem[] getCUProblems() {
	// Re-adjust the size of the problems if necessary and filter package problems
	if (this.problems != null) {
		CategorizedProblem[] filteredProblems = new CategorizedProblem[this.problemCount];
		int keep = 0;
		for (int i=0; i< this.problemCount; i++) {
			CategorizedProblem problem = this.problems[i];
			if (problem.getID() != IProblem.MissingNonNullByDefaultAnnotationOnPackage) {
				filteredProblems[keep++] = problem;
			} else if (this.compilationUnit != null) {
				if (CharOperation.equals(this.compilationUnit.getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME)) {
					filteredProblems[keep++] = problem;
				}
			}
		}
		if (keep < this.problemCount) {
			System.arraycopy(filteredProblems, 0, filteredProblems = new CategorizedProblem[keep], 0, keep);
			this.problemCount = keep;
		}
		this.problems = filteredProblems;
		if (this.maxProblemPerUnit > 0 && this.problemCount > this.maxProblemPerUnit){
			quickPrioritize(this.problems, 0, this.problemCount - 1);
			this.problemCount = this.maxProblemPerUnit;
			System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount]), 0, this.problemCount);
		}

		// Stable sort problems per source positions.
		Arrays.sort(this.problems, 0, this.problems.length, CompilationResult.PROBLEM_COMPARATOR);
		//quickSort(problems, 0, problems.length-1);
	}
//{ObjectTeams: safer:
	else
		return new CategorizedProblem[0];
// SH}
	return this.problems;
}

/**
 * Answer the tasks (TO-DO, ...) encountered during compilation.
 *
 * This is not a compiler internal API - it has side-effects !
 * It is intended to be used only once all problems have been detected,
 * and makes sure the problems slot as the exact size of the number of
 * problems.
 */
public CategorizedProblem[] getTasks() {
	// Re-adjust the size of the tasks if necessary.
	if (this.tasks != null) {

		if (this.taskCount != this.tasks.length) {
			System.arraycopy(this.tasks, 0, (this.tasks = new CategorizedProblem[this.taskCount]), 0, this.taskCount);
		}
		// Stable sort problems per source positions.
		Arrays.sort(this.tasks, 0, this.tasks.length, CompilationResult.PROBLEM_COMPARATOR);
		//quickSort(tasks, 0, tasks.length-1);
	}
	return this.tasks;
}

public boolean hasErrors() {
	return this.numberOfErrors != 0;
}

public boolean hasMandatoryErrors() {
	return this.hasMandatoryErrors;
}

public boolean hasProblems() {
	return this.problemCount != 0;
}

public boolean hasTasks() {
	return this.taskCount != 0;
}

public boolean hasWarnings() {
	if (this.problems != null)
		for (int i = 0; i < this.problemCount; i++) {
			if (this.problems[i].isWarning())
				return true;
		}
	return false;
}

private void quickPrioritize(CategorizedProblem[] problemList, int left, int right) {
	if (left >= right) return;
	// sort the problems by their priority... starting with the highest priority
	int original_left = left;
	int original_right = right;
	int mid = computePriority(problemList[left + (right - left) / 2]);
	do {
		while (computePriority(problemList[right]) < mid)
			right--;
		while (mid < computePriority(problemList[left]))
			left++;
		if (left <= right) {
			CategorizedProblem tmp = problemList[left];
			problemList[left] = problemList[right];
			problemList[right] = tmp;
			left++;
			right--;
		}
	} while (left <= right);
	if (original_left < right)
		quickPrioritize(problemList, original_left, right);
	if (left < original_right)
		quickPrioritize(problemList, left, original_right);
}

/*
 * Record the compilation unit result's package name
 */
public void recordPackageName(char[][] packName) {
	this.packageName = packName;
}

public void record(CategorizedProblem newProblem, ReferenceContext referenceContext) {
	record(newProblem, referenceContext, true);
	return;
}

public void record(CategorizedProblem newProblem, ReferenceContext referenceContext, boolean mandatoryError) {
	//new Exception("VERBOSE PROBLEM REPORTING").printStackTrace();
	if(newProblem.getID() == IProblem.Task) {
		recordTask(newProblem);
		return;
	}
	if (this.problemCount == 0) {
		this.problems = new CategorizedProblem[5];
	} else if (this.problemCount == this.problems.length) {
		System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount * 2]), 0, this.problemCount);
	}
	this.problems[this.problemCount++] = newProblem;
	if (referenceContext != null){
		if (this.problemsMap == null) this.problemsMap = new HashMap(5);
		if (this.firstErrors == null) this.firstErrors = new HashSet(5);
		if (newProblem.isError() && !referenceContext.hasErrors()) this.firstErrors.add(newProblem);
		this.problemsMap.put(newProblem, referenceContext);
	}
	if (newProblem.isError()) {
		this.numberOfErrors++;
		if (mandatoryError) this.hasMandatoryErrors = true;
		if ((newProblem.getID() & IProblem.Syntax) != 0) {
			this.hasSyntaxError = true;
		}
	}
}

ReferenceContext getContext(CategorizedProblem problem) {
	if (problem != null) {
		return this.problemsMap.get(problem);
	}
	return null;
}

/**
 * For now, remember the compiled type using its compound name.
 */
public void record(char[] typeName, ClassFile classFile) {
    SourceTypeBinding sourceType = classFile.referenceBinding;
    if (sourceType != null && !sourceType.isLocalType() && sourceType.isHierarchyInconsistent()) {
        this.hasInconsistentToplevelHierarchies = true;
    }
	this.compiledTypes.put(typeName, classFile);
}

private void recordTask(CategorizedProblem newProblem) {
	if (this.taskCount == 0) {
		this.tasks = new CategorizedProblem[5];
	} else if (this.taskCount == this.tasks.length) {
		System.arraycopy(this.tasks, 0, (this.tasks = new CategorizedProblem[this.taskCount * 2]), 0, this.taskCount);
	}
	this.tasks[this.taskCount++] = newProblem;
}
public void removeProblem(CategorizedProblem problem) {
	if (this.problemsMap != null) this.problemsMap.remove(problem);
	if (this.firstErrors != null) this.firstErrors.remove(problem);
	if (problem.isError()) {
		this.numberOfErrors--;
	}
	this.problemCount--;
}
public CompilationResult tagAsAccepted(){
	this.hasBeenAccepted = true;
	this.problemsMap = null; // flush
	this.firstErrors = null; // flush
	return this;
}

//{ObjectTeams: some problems might have been reported overeagerly, filter them now:
public void recheckProblems(IrritantSet[] foundIrritants) {
	int allProblemCount = this.problemCount;
	if (allProblemCount == 0) return;
	int j = 0;
	for (int i = 0; i < allProblemCount; i++)
		if (   (this.problems[i] instanceof DefaultProblem)
			&& ((DefaultProblem)this.problems[i]).shouldBeReported(foundIrritants)) // pass foundIrritants so the effective suppressions can be recorded
			this.problems[j++] = this.problems[i]; // move remaining problems to front, not handled by removeProblem
		else
			this.removeProblem(this.problems[i]);
	// don't bother with shrinking this.problems, will be done by getProblems()
}
// SH}

@Override
public String toString(){
	StringBuffer buffer = new StringBuffer();
	if (this.fileName != null){
		buffer.append("Filename : ").append(this.fileName).append('\n'); //$NON-NLS-1$
	}
	if (this.compiledTypes != null){
		buffer.append("COMPILED type(s)	\n");  //$NON-NLS-1$
		Iterator keys = this.compiledTypes.keySet().iterator();
		while (keys.hasNext()) {
			char[] typeName = (char[]) keys.next();
			buffer.append("\t - ").append(typeName).append('\n');   //$NON-NLS-1$

		}
	} else {
		buffer.append("No COMPILED type\n");  //$NON-NLS-1$
	}
//{ObjectTeams: debug for new field binaryMemberNames
	if (this.binaryMemberNames != null) {
		buffer.append("REUSED BINARY type(s)	\n");  //$NON-NLS-1$
		for (Iterator iter = this.binaryMemberNames.iterator(); iter.hasNext();) {
			char[] element = (char[]) iter.next();
			buffer.append("\t - ").append(element).append('\n');  //$NON-NLS-1$
		}
	} else {
		buffer.append("No REUSED BINARY type\n");  //$NON-NLS-1$
	}
// SH}
	if (this.problems != null){
		buffer.append(this.problemCount).append(" PROBLEM(s) detected \n"); //$NON-NLS-1$
		for (int i = 0; i < this.problemCount; i++){
			buffer.append("\t - ").append(this.problems[i]).append('\n'); //$NON-NLS-1$
		}
	} else {
		buffer.append("No PROBLEM\n"); //$NON-NLS-1$
	}
	return buffer.toString();
}
//{ObjectTeams: try to retrieve class file that has been generated but perhaps not yet written to disk:
public ClassFile findClassFile(ReferenceBinding typeBinding) {
	for (Object cfObj : this.compiledTypes.values()) {
		ClassFile classFile = (ClassFile) cfObj;
		if (TypeBinding.equalsEquals(classFile.referenceBinding, typeBinding))
			return classFile;
	}
	return null;
}
/**
 * Given a synthetic line number assign a unique synthetic source position.
 * @param syntheticLineNumber
 * @return a fresh source position that uniquely maps to the given synthetic line number
 */
public int requestSyntheticSourcePosition(int syntheticLineNumber) {
	int oldEndPos = this.lineSeparatorPositions[this.lineSeparatorPositions.length-1];
	if (this.sourceEndPos == Integer.MAX_VALUE)
		this.sourceEndPos = oldEndPos;
	int oldLen = this.lineSeparatorPositions.length;
	assert oldLen <= syntheticLineNumber : "Synthetic line numbers must be higher than existing ones."; //$NON-NLS-1$
	int newStartPos = oldEndPos;
	System.arraycopy(this.lineSeparatorPositions, 0, 
					 this.lineSeparatorPositions = new int[syntheticLineNumber], 0, oldLen);
	for (int i=oldLen; i<syntheticLineNumber; i++) {
		newStartPos += 2;
		this.lineSeparatorPositions[i] = newStartPos;
	}
	return newStartPos-1; // just before the last line end
}
// SH}
}
