/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 * 
 * Copyright 2004, 2006 Fraunhofer Gesellschaft, Munich, Germany,
 * for its Fraunhofer Institute for Computer Architecture and Software
 * Technology (FIRST), Berlin, Germany and Technical University Berlin,
 * Germany.
 * 
 * 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
 * 
 * Please visit http://www.eclipse.org/objectteams for updates and contact.
 * 
 * Contributors:
 * Fraunhofer FIRST - Initial API and implementation
 * Technical University Berlin - Initial API and implementation
 **********************************************************************/
package org.eclipse.objectteams.otdt.internal.compiler.adaptor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
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.objectteams.otdt.core.compiler.IOTConstants;

import base org.eclipse.jdt.core.compiler.CategorizedProblem;
import base org.eclipse.jdt.internal.compiler.CompilationResult;
import base org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; // base-class of a role file
import base org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
import base org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import base org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import base org.eclipse.jdt.internal.compiler.problem.AbortType;
import base org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import base org.eclipse.objectteams.otdt.internal.core.compiler.lifting.LiftingEnvironment;
import base org.eclipse.jdt.internal.core.builder.IncrementalImageBuilder; // base-class of a role file

/**
 * This Team observes the build/compile process and advises the IncrementalImageBuilder, 
 * when and what to recompile due to OT-specific dependencies.
 * 
 * @author stephan
 * @version $Id: BuildManager.java 23451 2010-02-04 20:33:32Z stephan $
 */
@SuppressWarnings("restriction")
public team class BuildManager extends CompilationThreadWatcher
{
	public static int DEBUG = 0; // levels: 0 nothing, 1 some, 2 more.

	/** Remember the (one) ImageBuilder role. */
	ImageBuilder builder = null;
	
	// ====== Data common for all roles (incl. accessors and life-cycle). ======
	
	
	/** Manage cross-ref table for copied roles:
	 *  PRODUCER: RoleCopyTracker.trackCopyRole()
	 *  CONSUMER: ClassFileChangeTracker.nonStructuralChange()
	 *  
	 *  ENCODING: RoleTypeName -> Set<TeamSourceFileName> */
	HashMap<String, Set<String>> roleToSubTeams = new HashMap<String, Set<String>>();
	
	void recordCopiedRole(char[] roleName, char[] subTeamSourceFileName) {
		String roleString = new String(roleName);
		Set<String> teams = roleToSubTeams.get(roleString);
		if (teams == null) 
			roleToSubTeams.put(roleString, teams = new HashSet<String>());
		teams.add(new String(subTeamSourceFileName));
		if (DEBUG >= 2)
			System.out.println("role "+roleString+" is COPIED to "+new String(subTeamSourceFileName));  //$NON-NLS-1$//$NON-NLS-2$
	}
//	// debug helper
//	void printCopyTable() {
//		System.out.print("-------------------------");
//		for (Map.Entry<String, Set<String>> entry : roleToSubTeams.entrySet()) {
//			System.out.print("\nRole "+entry.getKey());
//			for (String value : entry.getValue()) {
//				System.out.print("\n\t"+value);
//			}
//		}
//		System.out.println("\n-------------------------");
//	}
	
	/** If a tsuper role has non-structural changes, some sub-teams need to be recompiled.
	 *  This set holds the teams to be recompiled.
	 *
	 *  PRODUCERS: ClassFileChangeTracker.nonStructuralChange()
	 *  		   ImageBuilder.shouldPreserveBinary() (during compile->finishedWith)
	 *  CONSUMER:  ImageBuilder.addAffectedTeamFiles()
	 *  
	 *  ENCODING: source file name
	 */
	HashSet<String> teamsToRecompile = new HashSet<String>();
	
	/** Get and clear the set of teams waiting for recompilation. */
	HashSet<String> fetchTeamsToRecompile() {
		HashSet<String> result = teamsToRecompile;
		teamsToRecompile = new HashSet<String>();
		return result;
	}

	/** If a tsuper role has non-structural changes, some sub-teams need to be recompiled.
	 *  This set holds the roles that should NOT be preserved.
	 *  PRODUCER: ClassFileChangeTracker.nonStructuralChange()
	 *  CONSUMER: shouldPreserveBinary() (via shouldCandidateBePreserved())
	 *  
	 *  ENCODING: Qualified Type Name. p.T$I, canonical form, i.e., __OT__ prefixes removed.
	 */
	HashSet<String> staleRoles = new HashSet<String>();

	synchronized void initializeDependencyStorage() {
		this.roleToSubTeams = new HashMap<String, Set<String>>();
		this.teamsToRecompile = new HashSet<String>();
		this.staleRoles = new HashSet<String>();
	}
	
	/**
	 * We'll deactivate this BuildManager after MAX_RETRIES to avoid causing to fall back
	 * on a full build due to our attempts, which in certain situations could lead to
	 * an infinite build loop, see https://bugs.eclipse.org/417735
	 * To play safe MAX_RETRIES must be less than IncrementalImageBuilder.MaxCompileLoop.
	 */
	final static int MAX_RETRIES = 3;
	int retries = 0;

	public BuildManager start() {
		this.retries = 0;
		return this;
	}

	protected class BinaryType playedBy BinaryTypeBinding 
	{
		/** Record if a given type depends on an unresolvable type.
		 *  More specifically, we look for roles depending on unresolvable tsuper roles. 
		 */
		superInterfaces         <- replace superInterfaces;
		callin ReferenceBinding[] superInterfaces() {
			try { 
				return base.superInterfaces();
			} catch (AbortCompilation as Abort abort) {
				abort.referencedBinaries.add(this);
				throw abort;
			}
		}
		
		// ==== Callouts: ==== 
				
		char[][] compoundName() -> get char[][] compoundName;

		// DEBUGGING:
		String internalName() -> char[] internalName() 
			with { result <- new String(result) }
	}
	
	protected class ClassScope playedBy ClassScope
	{
		@SuppressWarnings("decapsulation")
		void connectTypeHierarchy() <- replace void connectTypeHierarchy();
		@SuppressWarnings("basecall")
		callin void connectTypeHierarchy() {
			try {
				base.connectTypeHierarchy();
			} catch (org.eclipse.jdt.internal.compiler.problem.AbortType at) {
				TypeDeclaration referenceContext = referenceContext();
				SourceTypeBinding sourceType = referenceContext.binding;
				at.updateContext(referenceContext, referenceCompilationUnit().compilationResult);
				referenceContext.ignoreFurtherInvestigation = true;
				if (sourceType.superInterfaces == null)
					sourceType.superInterfaces = TypeBinding.NO_SUPERINTERFACES; // TODO(SH): recurse?
				// don't rethrow, marking ignoreFurtherInvestigation is enough abortion
			}
		}
		TypeDeclaration referenceContext()                    -> get TypeDeclaration referenceContext;
		CompilationUnitDeclaration referenceCompilationUnit() -> CompilationUnitDeclaration referenceCompilationUnit();
	}

	protected class LiftingEnv playedBy LiftingEnvironment 
	{
		callin void init(TypeDeclaration teamType) {
			try {
				base.init(teamType);
			} catch (org.eclipse.jdt.internal.compiler.problem.AbortType at) {
				teamType.ignoreFurtherInvestigation = true;
				BuildManager.this.teamsToRecompile.add(String.valueOf(teamType.compilationResult.fileName));
				throw at; // TODO(SH): might want to mark certain AT-instances as recoverable?
			}
		}
		init <- replace init;
	}
	
	/** This role helps to link Problem->Abort->BinaryType,
	 *  in order to determine whether a problem was caused by an unresolvable tsuper role.  
	 */
	protected class Abort playedBy AbortCompilation 
	{
		public List<BinaryType> referencedBinaries = new ArrayList<BinaryType>();

		/** Trigger: this role has more to be updated from the context. */
		void updateContext(ASTNode astNode, CompileResult unitResult) 
			<- after void updateContext(ASTNode astNode, CompilationResult unitResult);

		/** 
		 * If the current abort exception could possibly be fixed by a recompile,
		 * + convert the exception onto a less drastic AbortType 
		 * + record the link Problem->Abort.
		 */
		public void updateContext(ASTNode astNode, CompileResult unitResult) {
			Problem problem = getProblem();
			if (   problem != null
				&& problem.couldBeFixedByRecompile()
				&& unitResult.isReusingBinaryMember()) 
			{ 
				// convert AbortCompilation into AbortType
				Abort abort = new AbortType(
								new org.eclipse.jdt.internal.compiler.problem.AbortType(
									unitResult, problem));
				abort.referencedBinaries = this.referencedBinaries;
				problem.abortException = abort;				
				RuntimeException ex = abort;
				throw ex;
			}
		}
	
		protected Problem getProblem() -> get CategorizedProblem problem;
	}
	
	protected class AbortType extends Abort playedBy AbortType 
	{
//		// FIXME : this ctor gives a VerifyError:
//		AbortType (CompileResult result, Problem problem) {
//			base(result, problem);
//			problem.abortException = this;
//		}
		@Override
		public void updateContext(ASTNode astNode, CompileResult unitResult) {
			// no super call: would cause recursive creation of roles
			Problem problem = getProblem();
			if (problem != null) {
				problem.abortException = this;
			}
		}
	}
	
	/** Intermediate purely callout role. */
	protected class CompileResult playedBy CompilationResult
	{
	  protected // don't publically export protected role Problem
		Problem[] problems()                     -> get CategorizedProblem[] problems;
		
		// TODO(SH): workaround for lowering problem concerning base call in ImageBuilder.shouldPreserveBinary() 
		boolean hasBinaryMember(char[] typeName) ->     boolean hasBinaryMember(char[] typeName);
		
		@SuppressWarnings({"decapsulation", "rawtypes"})
	  protected
		boolean isReusingBinaryMember() 		 -> get ArrayList binaryMemberNames
			with { result <- !(result == null || result.isEmpty()) }
		
		char[] getFileName() -> char[] getFileName();
		// debugging:
		toString => toString;
	}
	
	/** Let a problem know about the associated exception. */
	protected class Problem playedBy CategorizedProblem 
	{
		public Abort abortException = null;
		public char[] typeToRemove= null;
	
		/** Certain problem reasons might be fixed by recompilation. */
		protected boolean couldBeFixedByRecompile() {
			switch (getID()) {
			case IProblem.IsClassPathCorrect:
			case IProblem.StaleTSuperRole:
			case IProblem.StaleSubRole:
			case IProblem.MissingRoleInBinaryTeam:
			case IProblem.RoleFileInBinaryTeam:
			case IProblem.CorruptBytecode:
			case IProblem.MissingAccessorInBinary:
			case IProblem.MismatchingRoleParts:
			case IProblem.InconsistentlyResolvedRole:
			case IProblem.NotGeneratingCallinBinding:
				return true;
			default:
				return false;
			}
		}
		
		int getID() -> int getID();
		// debugging:
		toString => getMessage;
	}

	/** Watch specific error reports. */
	protected class ProblemReporter playedBy ProblemReporter {

		// a missing role in a binary team means the binary team should probably be deleted.
		void missingRoleInBinaryTeam(ReferenceBinding type)
		<- replace void missingRoleInBinaryTeam(char[] roleName, ReferenceBinding enclosingTeam)
			with { type <- enclosingTeam }

		callin void missingRoleInBinaryTeam(ReferenceBinding type) {
			ReferenceContext context= getReferenceContext();
			try {
				base.missingRoleInBinaryTeam(type);
			} finally {
				if (context != null && context.compilationResult() != null) {			
					int count= context.compilationResult().problemCount;
					recordTypeToRemove(context.compilationResult().problems[count-1], 
										  type.constantPoolName());
				}
			}
		}

		ReferenceContext getReferenceContext() -> get ReferenceContext referenceContext;
	}

	// ---- ImageBuilder is a role file ---- 

	
	// ---- Team level features: ----
	void recordTypeToRemove(CategorizedProblem as Problem prob, char[] roleName) {
		prob.typeToRemove= roleName;
	}

	public static boolean isPredefinedRole(char[] roleName) {
		int dollarPos = CharOperation.lastIndexOf('$', roleName);
		if (dollarPos != -1) 
			roleName = CharOperation.subarray(roleName, dollarPos+1, -1);
		return CharOperation.equals(roleName, IOTConstants.CONFINED)
			|| CharOperation.equals(roleName, IOTConstants.OTCONFINED)
			|| CharOperation.equals(roleName, IOTConstants.ICONFINED)
			|| CharOperation.equals(roleName, IOTConstants.IBOUNDBASE)
			|| CharOperation.equals(roleName, IOTConstants.IBOUNDBASE2)
			|| CharOperation.equals(roleName, IOTConstants.ILOWERABLE);					
	}
	
	/** Answer whether the given role type should be re-used (ask the ImageBuilder). */
	public boolean shouldPreserveBinaryRole(ReferenceBinding role, CompilationResult as CompileResult cResult) {
		if (builder == null)
			return true;
		return builder.shouldPreserveBinaryRole(role, cResult);
	}
	
	public String canonicalName(String roleName) {
		return roleName.replace(IOTConstants.OT_DELIM, ""); //$NON-NLS-1$
	}
}
