/*******************************************************************************
 * Copyright (c) 2005, 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
 *     Simon Scholz <simon.scholz@vogella.com> - Ongoing maintenance
 *******************************************************************************/
package org.eclipse.core.tools.search;

import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.dom.*;
import org.eclipse.jdt.core.search.*;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory;
import org.eclipse.jface.operation.IRunnableWithProgress;

/*
 * Class that removes field declarations which aren't referenced.
 */
public class FindUnusedMembers implements IRunnableWithProgress {

	public static interface IResultReporter {
		void unusedElementFound(IMember member) throws CoreException;
	}

	public static class OutputWriter implements IResultReporter {

		private final Writer output;
		private IType lastType;

		public OutputWriter(Writer writer) {
			output = writer;
		}

		@Override
		public void unusedElementFound(IMember member) throws CoreException {
			try {
				if (!member.getDeclaringType().equals(lastType)) {
					lastType = member.getDeclaringType();
					writeHeader(lastType);
				}
				if (member instanceof IMethod) {
					writeResult((IMethod) member);
				} else if (member instanceof IField) {
					writeResult((IField) member);
				}
			} catch (IOException e) {
				// to do
			}
		}

		private void writeHeader(IType type) throws IOException {
			output.write("\n\n" + type.getFullyQualifiedName()); //$NON-NLS-1$
		}

		private void writeResult(IField field) throws IOException, JavaModelException {
			output.write("\n\t"); //$NON-NLS-1$
			output.write(Signature.toString(field.getTypeSignature()));
			output.write(" "); //$NON-NLS-1$
			output.write(field.getElementName());
		}

		private void writeResult(IMethod method) throws IOException, JavaModelException {
			output.write("\n\t");//$NON-NLS-1$
			output.write(Signature.toString(method.getReturnType()));
			output.write(" "); //$NON-NLS-1$
			output.write(method.getElementName());
			output.write("("); //$NON-NLS-1$
			String[] types = method.getParameterTypes();
			for (int i = 0; i < types.length; i++) {
				output.write(Signature.toString(types[i]));
				if (i < types.length - 1)
					output.write(","); //$NON-NLS-1$
			}
			output.write(")"); //$NON-NLS-1$
		}
	}

	private final IResultReporter result;
	private ICompilationUnit[] units;
	protected int unusedMemberCount = 0;

	public FindUnusedMembers(ICompilationUnit[] units, Writer writer) {
		this(units, new OutputWriter(writer));
	}

	public FindUnusedMembers(ICompilationUnit[] units, IResultReporter resultReporter) {
		this.units = units;
		this.result = resultReporter;
	}

	private void doSearchCU(ICompilationUnit cu, IProgressMonitor monitor) throws CoreException {
		IType[] allTypes = cu.getAllTypes();
		SubMonitor subMonitor = SubMonitor.convert(monitor, "Processing " + cu.getElementName(), allTypes.length + 1); //$NON-NLS-1$

		ASTParser astParser = ASTParser.newParser(AST.JLS8);
		astParser.setResolveBindings(true);
		astParser.setProject(cu.getJavaProject());

		IBinding[] bindings = astParser.createBindings(allTypes, subMonitor.newChild(1));
		for (IBinding binding : bindings) {
			if (monitor.isCanceled())
				throw new OperationCanceledException();
			ITypeBinding typeBinding = (ITypeBinding) binding;
			subMonitor.setTaskName("Processing '" + typeBinding.getQualifiedName() + "'"); //$NON-NLS-1$//$NON-NLS-2$
			doSearchType(typeBinding, subMonitor.newChild(1));
		}
	}

	private boolean methodOverrides(IMethodBinding binding) {
		return Bindings.findOverriddenMethod(binding, true) != null;
	}

	public void doSearchType(ITypeBinding typeBinding, IProgressMonitor monitor) throws CoreException {
		IMethodBinding[] methods = typeBinding.getDeclaredMethods();
		IVariableBinding[] fields = typeBinding.getDeclaredFields();
		SubMonitor subMonitor = SubMonitor.convert(monitor, "Searching for references.", //$NON-NLS-1$
				methods.length + fields.length);

		for (IMethodBinding methodBinding : methods) {
			if (monitor.isCanceled())
				throw new OperationCanceledException();

			if (methodOverrides(methodBinding))
				continue;

			IMethod method = (IMethod) methodBinding.getJavaElement();
			if (method == null)
				continue;

			if (hasReferences(method, subMonitor.newChild(1)))
				continue;
			result.unusedElementFound(method);
			unusedMemberCount++;
		}
		for (IVariableBinding fieldBinding : fields) {
			IField field = (IField) fieldBinding.getJavaElement();
			if (field == null)
				continue;
			if (hasReferences(field, subMonitor.split(1)))
				continue;
			result.unusedElementFound(field);
			unusedMemberCount++;
		}

		if (monitor.isCanceled())
			throw new OperationCanceledException();
	}

	public int getUnusedMethodCount() {
		return unusedMemberCount;
	}

	private boolean hasReferences(IMember member, IProgressMonitor monitor) throws JavaModelException {

		final class ReferenceFound extends Error {
			private static final long serialVersionUID = 1L;
		}

		try {
			IJavaSearchScope searchScope = RefactoringScopeFactory.create(member.getDeclaringType());
			SearchPattern pattern = SearchPattern.createPattern(member, IJavaSearchConstants.REFERENCES);
			SearchRequestor requestor = new SearchRequestor() {
				@Override
				public void acceptSearchMatch(SearchMatch match) throws CoreException {
					if (match.getAccuracy() == SearchMatch.A_ACCURATE) {
						throw new ReferenceFound();
					}
				}
			};
			new SearchEngine().search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() },
					searchScope, requestor, monitor);
		} catch (CoreException e) {
			throw new JavaModelException(e);
		} catch (ReferenceFound e) {
			return true;
		}
		return false;
	}

	public void process(IProgressMonitor monitor) throws CoreException {
		SubMonitor subMonitor = SubMonitor.convert(monitor, "Searching unused members", this.units.length); //$NON-NLS-1$
		for (ICompilationUnit unit : this.units) {
			doSearchCU(unit, subMonitor.split(1));
		}
	}

	@Override
	public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
		try {
			process(monitor);
		} catch (OperationCanceledException e) {
			throw new InterruptedException();
		} catch (CoreException e) {
			throw new InvocationTargetException(e);
		}
	}

}
