/*******************************************************************************
 * Copyright (c) 2008, 2015 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
 *******************************************************************************/
package org.eclipse.pde.api.tools.internal.builder;

import java.text.MessageFormat;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.pde.api.tools.internal.provisional.ApiDescriptionVisitor;
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
import org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations;
import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers;
import org.eclipse.pde.api.tools.internal.provisional.builder.IApiProblemDetector;
import org.eclipse.pde.api.tools.internal.provisional.builder.IReference;
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor;
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IPackageDescriptor;
import org.eclipse.pde.api.tools.internal.provisional.model.ApiTypeContainerVisitor;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiType;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeRoot;
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;

/**
 * The reference analyzer
 *
 * @since 1.1
 */
public class ReferenceAnalyzer {

	/**
	 * Natural log of 2.
	 */
	private static final double LOG2 = Math.log(2);

	/**
	 * Empty result collection.
	 */
	private static final IApiProblem[] EMPTY_RESULT = new IApiProblem[0];
	/**
	 * No problem detector to use
	 */
	private static final IApiProblemDetector[] NO_PROBLEM_DETECTORS = new IApiProblemDetector[0];

	/**
	 * Visits each class file, extracting references.
	 */
	class Visitor extends ApiTypeContainerVisitor {

		private IProgressMonitor fMonitor = null;

		public Visitor(IProgressMonitor monitor) {
			fMonitor = monitor;
		}

		@Override
		public boolean visitPackage(String packageName) {
			fMonitor.subTask(MessageFormat.format(BuilderMessages.ReferenceAnalyzer_checking_api_used_by, packageName));
			return true;
		}

		@Override
		public void endVisitPackage(String packageName) {
			fMonitor.worked(1);
		}

		@Override
		public void visit(String packageName, IApiTypeRoot classFile) {
			if (!fMonitor.isCanceled()) {
				try {
					IApiType type = classFile.getStructure();
					if (type == null) {
						// do nothing for bad class files
						return;
					}
					// don't process inner/anonymous/local types, this is done
					// in the extractor
					if (type.isMemberType() || type.isLocal() || type.isAnonymous()) {
						return;
					}
					List<IReference> references = type.extractReferences(fAllReferenceKinds, null);
					// keep potential matches
					for (IReference ref : references) {
						if (fMonitor.isCanceled()) {
							break;
						}
						// compute index of interested problem detectors
						int index = getLog2(ref.getReferenceKind());
						IApiProblemDetector[] detectors = fIndexedDetectors[index];
						boolean added = false;
						if (detectors != null) {
							for (IApiProblemDetector detector : detectors) {
								if (fMonitor.isCanceled()) {
									break;
								}
								if (detector.considerReference(ref, fMonitor)) {
									if (!added) {
										fReferences.add(ref);
										added = true;
									}
								}
							}
						}
					}
				} catch (CoreException e) {
					fStatus.add(e.getStatus());
					AbstractProblemDetector.checkIfDisposed(classFile.getApiComponent(), fMonitor);
				}
			}
		}
	}

	/**
	 * Scan status
	 */
	MultiStatus fStatus;

	/**
	 * Bit mask of reference kinds that problem detectors care about.
	 */
	int fAllReferenceKinds = 0;

	/**
	 * List of references to consider/resolve.
	 */
	List<IReference> fReferences = new LinkedList<>();

	/**
	 * Problem detectors indexed by the log base 2 of each reference kind they
	 * are interested in. Provides a fast way to hand references off to
	 * interested problem detectors.
	 */
	IApiProblemDetector[][] fIndexedDetectors;

	/**
	 * Indexes the problem detectors by the reference kinds they are interested
	 * in. For example, a detector interested in a
	 * {@link org.eclipse.pde.api.tools.internal.provisional.search.ReferenceModifiers#REF_INSTANTIATE}
	 * will be in the 26th index (0x1 << 27, which is 2 ^ 26). Also initializes
	 * the bit mask of all interesting reference kinds.
	 *
	 * @param detectors problem detectors
	 */
	void indexProblemDetectors(IApiProblemDetector[] detectors) {
		fIndexedDetectors = new IApiProblemDetector[32][];
		for (IApiProblemDetector detector : detectors) {
			int kinds = detector.getReferenceKinds();
			fAllReferenceKinds |= kinds;
			int mask = 0x1;
			for (int bit = 0; bit < 32; bit++) {
				if ((mask & kinds) > 0) {
					IApiProblemDetector[] indexed = fIndexedDetectors[bit];
					if (indexed == null) {
						fIndexedDetectors[bit] = new IApiProblemDetector[] { detector };
					} else {
						IApiProblemDetector[] next = new IApiProblemDetector[indexed.length + 1];
						System.arraycopy(indexed, 0, next, 0, indexed.length);
						next[indexed.length] = detector;
						fIndexedDetectors[bit] = next;
					}
				}
				mask = mask << 1;
			}
		}
	}

	/**
	 * log 2 (x) = ln(x) / ln(2)
	 *
	 * @param bitConstant a single bit constant (0x1 << n)
	 * @return log base 2 of the constant (the power of 2 the constant is equal
	 *         to)
	 */
	int getLog2(int bitConstant) {
		double logX = Math.log(bitConstant);
		double pow = logX / LOG2;
		return (int) Math.round(pow);
	}

	/**
	 * Scans the given scope extracting all reference information.
	 *
	 * @param scope scope to scan
	 * @param monitor progress monitor
	 * @exception CoreException if the scan fails
	 */
	void extractReferences(IApiTypeContainer scope, IProgressMonitor monitor) throws CoreException {
		fStatus = new MultiStatus(ApiPlugin.PLUGIN_ID, 0, BuilderMessages.ReferenceAnalyzer_api_analysis_error, null);
		String[] packageNames = scope.getPackageNames();
		SubMonitor localMonitor = SubMonitor.convert(monitor, packageNames.length);
		ApiTypeContainerVisitor visitor = new Visitor(localMonitor);
		long start = System.currentTimeMillis();
		try {
			scope.accept(visitor);
		} catch (CoreException e) {
			fStatus.add(e.getStatus());
		}
		long end = System.currentTimeMillis();
		if (!fStatus.isOK()) {
			throw new CoreException(fStatus);
		}
		localMonitor.done();
		if (ApiPlugin.DEBUG_REFERENCE_ANALYZER) {
			System.out.println("Reference Analyzer: extracted " + fReferences.size() + " references in " + (end - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
	}

	/**
	 * Analyzes the given {@link IApiComponent} within the given
	 * {@link IApiTypeContainer} (scope) and returns a collection of detected
	 * {@link IApiProblem}s or an empty collection, never <code>null</code>
	 *
	 * @param component
	 * @param scope
	 * @param monitor
	 * @return the collection of detected {@link IApiProblem}s or an empty
	 *         collection, never <code>null</code>
	 * @throws CoreException
	 */
	public IApiProblem[] analyze(IApiComponent component, IApiTypeContainer scope, IProgressMonitor monitor) throws CoreException {
		SubMonitor localMonitor = SubMonitor.convert(monitor, 4);
		// build problem detectors
		IApiProblemDetector[] detectors = buildProblemDetectors(component, ProblemDetectorBuilder.K_ALL, localMonitor.split(1));
		// analyze
		try {
			// 1. extract references
			localMonitor.subTask(BuilderMessages.ReferenceAnalyzer_analyzing_api_checking_use);
			extractReferences(scope, localMonitor.split(1));
			// 2. resolve problematic references
			localMonitor.subTask(BuilderMessages.ReferenceAnalyzer_analyzing_api_checking_use);
			if (fReferences.size() != 0) {
				ReferenceResolver.resolveReferences(fReferences, localMonitor.split(1));
			}
			// 3. create problems
			List<IApiProblem> allProblems = new LinkedList<>();
			localMonitor.subTask(BuilderMessages.ReferenceAnalyzer_analyzing_api_checking_use);
			SubMonitor loopMonitor = localMonitor.split(1).setWorkRemaining(detectors.length);
			for (IApiProblemDetector detector : detectors) {
				if (monitor.isCanceled()) {
					break;
				}
				allProblems.addAll(detector.createProblems(loopMonitor.split(1)));
			}
			IApiProblem[] array = allProblems.toArray(new IApiProblem[allProblems.size()]);
			return array;
		} catch (OperationCanceledException e) {
			return EMPTY_RESULT;
		} finally {
			// clean up
			fIndexedDetectors = null;
			fReferences.clear();
		}
	}

	/**
	 * Returns the collection of problem detectors for the given reference kind
	 *
	 * @param referencekind
	 * @return
	 */
	public IApiProblemDetector[] getProblemDetectors(int referencekind) {
		if (fIndexedDetectors != null) {
			int index = getLog2(referencekind);
			if (index > -1 && index < fIndexedDetectors.length) {
				IApiProblemDetector[] detectors = fIndexedDetectors[index];
				if (detectors != null) {
					return detectors;
				}
			}
			return NO_PROBLEM_DETECTORS;
		}
		return NO_PROBLEM_DETECTORS;
	}

	/**
	 * Builds problem detectors to use when analyzing the given component.
	 *
	 * @param component component to be analyzed
	 * @param kindmask the kinds of detectors to build. See
	 *            {@link ProblemDetectorBuilder} for kinds
	 * @param monitor
	 *
	 * @return problem detectors
	 */
	public IApiProblemDetector[] buildProblemDetectors(IApiComponent component, int kindmask, IProgressMonitor monitor) {
		try {
			long start = System.currentTimeMillis();
			IApiComponent[] components = component.getBaseline().getPrerequisiteComponents(new IApiComponent[] { component });
			final ProblemDetectorBuilder visitor = new ProblemDetectorBuilder(component, kindmask);
			SubMonitor loopMonitor = SubMonitor.convert(monitor, components.length);
			for (IApiComponent componentLoop : components) {
				SubMonitor iterationMonitor = loopMonitor.split(1);
				IApiComponent prereq = componentLoop;
				if (!prereq.equals(component)) {
					visitor.setOwningComponent(prereq);
					try {
						prereq.getApiDescription().accept(visitor, iterationMonitor);
					} catch (CoreException e) {
						ApiPlugin.log(e.getStatus());
					}
				}
			}
			long end = System.currentTimeMillis();
			if (ApiPlugin.DEBUG_REFERENCE_ANALYZER) {
				System.out.println("Time to build problem detectors: " + (end - start) + "ms"); //$NON-NLS-1$//$NON-NLS-2$
			}
			// add names from the leak component as well
			ApiDescriptionVisitor nameVisitor = new ApiDescriptionVisitor() {
				@Override
				public boolean visitElement(IElementDescriptor element, IApiAnnotations description) {
					if (element.getElementType() == IElementDescriptor.PACKAGE) {
						if (VisibilityModifiers.isPrivate(description.getVisibility())) {
							visitor.addNonApiPackageName(((IPackageDescriptor) element).getName());
						}
					}
					return false;
				}
			};
			component.getApiDescription().accept(nameVisitor, null);
			List<IApiProblemDetector> detectors = visitor.getProblemDetectors();
			int size = detectors.size();
			if (size == 0) {
				return NO_PROBLEM_DETECTORS;
			}
			IApiProblemDetector[] array = detectors.toArray(new IApiProblemDetector[size]);
			indexProblemDetectors(array);
			return array;
		} catch (CoreException e) {
			ApiPlugin.log(e);
		}
		return NO_PROBLEM_DETECTORS;
	}
}
