/*******************************************************************************
 * Copyright (c) 2000, 2016 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.internal.ui.compare;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;

import org.eclipse.core.resources.IResource;

import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;

import org.eclipse.ui.services.IDisposable;

import org.eclipse.compare.CompareUI;
import org.eclipse.compare.IEditableContent;
import org.eclipse.compare.IEditableContentExtension;
import org.eclipse.compare.IResourceProvider;
import org.eclipse.compare.ISharedDocumentAdapter;
import org.eclipse.compare.IStreamContentAccessor;
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.compare.structuremergeviewer.DocumentRangeNode;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.compare.structuremergeviewer.IDiffContainer;
import org.eclipse.compare.structuremergeviewer.IDiffElement;
import org.eclipse.compare.structuremergeviewer.IStructureComparator;
import org.eclipse.compare.structuremergeviewer.StructureCreator;
import org.eclipse.compare.structuremergeviewer.StructureRootNode;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.compiler.IScanner;
import org.eclipse.jdt.core.compiler.ITerminalSymbols;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;


import org.eclipse.jdt.ui.text.IJavaPartitions;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.corext.dom.IASTSharedValues;


public class JavaStructureCreator extends StructureCreator {

	private Map<String, String> fDefaultCompilerOptions;

	/**
	 * A root node for the structure. It is similar to {@link StructureRootNode} but needed
	 * to be a subclass of {@link JavaNode} because of the code used to build the structure.
	 */
	private final class RootJavaNode extends JavaNode implements IDisposable {

		private final Object fInput;
		private final boolean fEditable;
		private final ISharedDocumentAdapter fAdapter;

		private RootJavaNode(IDocument document, boolean editable, Object input, ISharedDocumentAdapter adapter) {
			super(document);
			this.fEditable = editable;
			fInput= input;
			fAdapter= adapter;
		}

		@Override
		public boolean isEditable() {
			return fEditable;
		}

		@Override
		protected void nodeChanged(DocumentRangeNode node) {
			save(this, fInput);
		}

		@Override
		public void dispose() {
			if (fAdapter != null) {
				fAdapter.disconnect(fInput);
			}
		}

		@SuppressWarnings("unchecked")
		@Override
		public <T> T getAdapter(Class<T> adapter) {
			if (adapter == ISharedDocumentAdapter.class) {
				return (T) fAdapter;
			}
			return super.getAdapter(adapter);
		}


		@Override
		public boolean isReadOnly() {
			if (fInput instanceof IEditableContentExtension) {
				IEditableContentExtension ext = (IEditableContentExtension) fInput;
				return ext.isReadOnly();
			}
			return super.isReadOnly();
		}

		@Override
		public IStatus validateEdit(Shell shell) {
			if (fInput instanceof IEditableContentExtension) {
				IEditableContentExtension ext = (IEditableContentExtension) fInput;
				return ext.validateEdit(shell);
			}
			return super.validateEdit(shell);
		}
	}

	/**
	 * RewriteInfos are used temporarily when rewriting the diff tree
	 * in order to combine similar diff nodes ("smart folding").
	 */
	static class RewriteInfo {

		boolean fIsOut= false;

		JavaNode fAncestor= null;
		JavaNode fLeft= null;
		JavaNode fRight= null;

		ArrayList<IDiffElement> fChildren= new ArrayList<>();

		void add(IDiffElement diff) {
			fChildren.add(diff);
		}

		void setDiff(ICompareInput diff) {
			if (fIsOut)
				return;

			fIsOut= true;

			JavaNode a= (JavaNode) diff.getAncestor();
			JavaNode y= (JavaNode) diff.getLeft();
			JavaNode m= (JavaNode) diff.getRight();

			if (a != null) {
				if (fAncestor != null)
					return;
				fAncestor= a;
			}
			if (y != null) {
				if (fLeft != null)
					return;
				fLeft= y;
			}
			if (m != null) {
				if (fRight != null)
					return;
				fRight= m;
			}

			fIsOut= false;
		}

		/**
		 * @return true if some nodes could be successfully combined into one
		 */
		boolean matches() {
			return !fIsOut && fAncestor != null && fLeft != null && fRight != null;
		}
	}

	public JavaStructureCreator() {
	}

	void setDefaultCompilerOptions(Map<String, String> compilerSettings) {
		fDefaultCompilerOptions= compilerSettings;
	}

	/**
	 * @return the name that appears in the enclosing pane title bar
	 */
	@Override
	public String getName() {
		return CompareMessages.JavaStructureViewer_title;
	}

	/**
	 * @param input implement the IStreamContentAccessor interface
	 * @return a tree of JavaNodes for the given input.
	 * In case of error null is returned.
	 */
	@Override
	public IStructureComparator getStructure(final Object input) {
		String contents= null;
		char[] buffer= null;
		IDocument doc= CompareUI.getDocument(input);
		if (doc == null) {
			if (input instanceof IStreamContentAccessor) {
				IStreamContentAccessor sca= (IStreamContentAccessor) input;
				try {
					contents= JavaCompareUtilities.readString(sca);
				} catch (CoreException ex) {
					// return null indicates the error.
					return null;
				}
			}

			if (contents != null) {
				int n= contents.length();
				buffer= new char[n];
				contents.getChars(0, n, buffer, 0);

				doc= new Document(contents);
				setupDocument(doc);
			}
		}

		return createStructureComparator(input, buffer, doc, null, null);
	}

	@Override
	protected IStructureComparator createStructureComparator(Object element,
			IDocument document, ISharedDocumentAdapter sharedDocumentAdapter,
			IProgressMonitor monitor) throws CoreException {
		return createStructureComparator(element, null, document, sharedDocumentAdapter, monitor);
	}

	private IStructureComparator createStructureComparator(final Object input, char[] buffer, IDocument doc, ISharedDocumentAdapter adapter, IProgressMonitor monitor) {
		String contents;
		Map<String, String> compilerOptions= null;

		if (input instanceof IResourceProvider) {
			IResource resource= ((IResourceProvider) input).getResource();
			if (resource != null) {
				IJavaElement element= JavaCore.create(resource);
				if (element != null) {
					IJavaProject javaProject= element.getJavaProject();
					if (javaProject != null)
						compilerOptions= javaProject.getOptions(true);
				}
			}
		}
		if (compilerOptions == null)
			compilerOptions= fDefaultCompilerOptions;

		if (doc != null) {
			boolean isEditable= false;
			if (input instanceof IEditableContent)
				isEditable= ((IEditableContent) input).isEditable();

			// we hook into the root node to intercept all node changes
			JavaNode root= new RootJavaNode(doc, isEditable, input, adapter);

			if (buffer == null) {
				contents= doc.get();
				int n= contents.length();
				buffer= new char[n];
				contents.getChars(0, n, buffer, 0);
			}

			ASTParser parser= ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL);
			if (compilerOptions != null)
				parser.setCompilerOptions(compilerOptions);
			parser.setSource(buffer);
			parser.setFocalPosition(0);
			CompilationUnit cu= (CompilationUnit) parser.createAST(monitor);
			cu.accept(new JavaParseTreeBuilder(root, buffer, true));

			return root;
		}
		return null;
	}

	/**
	 * Returns the contents of the given node as a string.
	 * This string is used to test the content of a Java element
	 * for equality. Is is never shown in the UI, so any string representing
	 * the content will do.
	 * @param node must implement the IStreamContentAccessor interface
	 * @param ignoreWhiteSpace if <code>true</code> all Java white space (including comments) is removed from the contents.
	 * @return contents for equality test
	 */
	@Override
	public String getContents(Object node, boolean ignoreWhiteSpace) {

		if (! (node instanceof IStreamContentAccessor))
			return null;


		IStreamContentAccessor sca= (IStreamContentAccessor) node;
		String content= null;
		try {
			content= JavaCompareUtilities.readString(sca);
		} catch (CoreException ex) {
			JavaPlugin.log(ex);
			return null;
		}


		if (!ignoreWhiteSpace)
			return content;

		// replace whitespace by a single blank
		StringBuffer buf= new StringBuffer();
		char[] b= content.toCharArray();

		// to avoid the trouble when dealing with Unicode
		// we use the Java scanner to extract non-whitespace and comment tokens
		IScanner scanner= ToolFactory.createScanner(true, false, false, false); // however we request Whitespace and Comments
		scanner.setSource(b);
		try {
			int token;
			while ((token= scanner.getNextToken()) != ITerminalSymbols.TokenNameEOF) {
				char[] currentTokenSource= scanner.getCurrentTokenSource();
				switch (token) {
					case ITerminalSymbols.TokenNameCOMMENT_LINE:
					case ITerminalSymbols.TokenNameCOMMENT_BLOCK:
					case ITerminalSymbols.TokenNameCOMMENT_JAVADOC:
						StringBuffer tokenStr= new StringBuffer(currentTokenSource.length);
						tokenStr.append(currentTokenSource);
						StringTokenizer tokenizer= new StringTokenizer(tokenStr.toString());
						while (tokenizer.hasMoreTokens()) {
							buf.append(tokenizer.nextToken());
							buf.append(' ');
						}
						break;
					default:
						buf.append(currentTokenSource);
						buf.append(' ');
						break;
				}
			}
			content= buf.toString(); // success!
		} catch (InvalidInputException ex) {
			// NeedWork
		}
		return content;
	}

	/**
	 * @return true since this IStructureCreator can rewrite the diff tree
	 * in order to fold certain combinations of additions and deletions.
	 */
	public boolean canRewriteTree() {
		return true;
	}

	/**
	 * Tries to detect certain combinations of additions and deletions as renames or signature
	 * changes and folders them into a single node.
	 * 
	 * @param differencer the differencer
	 * @param root the diff container root
	 */
	public void rewriteTree(Differencer differencer, IDiffContainer root) {

		HashMap<String, RewriteInfo> map= new HashMap<>(10);

		Object[] children= root.getChildren();
		for (int i= 0; i < children.length; i++) {
			DiffNode diff= (DiffNode) children[i];
			JavaNode jn= (JavaNode) diff.getId();

			if (jn == null)
				continue;
			int type= jn.getTypeCode();

			// we can only combine methods or constructors
			if (type == JavaNode.METHOD || type == JavaNode.CONSTRUCTOR) {

				// find or create a RewriteInfo for all methods with the same name
				String name= jn.extractMethodName();
				RewriteInfo nameInfo= map.get(name);
				if (nameInfo == null) {
					nameInfo= new RewriteInfo();
					map.put(name, nameInfo);
				}
				nameInfo.add(diff);

				// find or create a RewriteInfo for all methods with the same
				// (non-empty) argument list
				String argList= jn.extractArgumentList();
				RewriteInfo argInfo= null;
				if (argList != null && !argList.equals("()")) { //$NON-NLS-1$
					argInfo= map.get(argList);
					if (argInfo == null) {
						argInfo= new RewriteInfo();
						map.put(argList, argInfo);
					}
					argInfo.add(diff);
				}

				switch (diff.getKind() & Differencer.CHANGE_TYPE_MASK) {
				case Differencer.ADDITION:
				case Differencer.DELETION:
					// we only consider addition and deletions
					// since a rename or argument list change looks
					// like a pair of addition and deletions
					if (type != JavaNode.CONSTRUCTOR)
						nameInfo.setDiff(diff);

					if (argInfo != null)
						argInfo.setDiff(diff);
					break;
				default:
					break;
				}
			}

			// recurse
			rewriteTree(differencer, diff);
		}

		// now we have to rebuild the diff tree according to the combined
		// changes
		Iterator<String> it= map.keySet().iterator();
		while (it.hasNext()) {
			String name= it.next();
			RewriteInfo i= map.get(name);
			if (i.matches()) { // we found a RewriteInfo that could be successfully combined

				// we have to find the differences of the newly combined node
				// (because in the first pass we only got a deletion and an addition)
				DiffNode d= (DiffNode) differencer.findDifferences(true, null, root, i.fAncestor, i.fLeft, i.fRight);
				if (d != null) {// there better should be a difference
					d.setDontExpand(true);
					Iterator<IDiffElement> it2= i.fChildren.iterator();
					while (it2.hasNext()) {
						IDiffElement rd= it2.next();
						root.removeToRoot(rd);
						d.add(rd);
					}
				}
			}
		}
	}

	/**
	 * The JavaHistoryAction uses this function to determine whether
	 * a selected Java element can be replaced by some piece of
	 * code from the local history.
	 * @param je Java element
	 * @return true if the given IJavaElement maps to a JavaNode
	 */
	static boolean hasEdition(IJavaElement je) {
		return JavaElementHistoryPageSource.hasEdition(je);
	}

	@Override
	protected IDocumentPartitioner getDocumentPartitioner() {
		return JavaCompareUtilities.createJavaPartitioner();
	}

	@Override
	protected String getDocumentPartitioning() {
		return IJavaPartitions.JAVA_PARTITIONING;
	}

	@Override
	protected String[] getPath(Object element, Object input) {
		if (element instanceof IJavaElement) {
			IJavaElement je = (IJavaElement) element;
			// build a path starting at the given Java element and walk
			// up the parent chain until we reach a IWorkingCopy or ICompilationUnit
			List<String> args= new ArrayList<>();
			while (je != null) {
				// each path component has a name that uses the same
				// conventions as a JavaNode name
				String name= JavaCompareUtilities.getJavaElementID(je);
				if (name == null)
					return null;
				args.add(name);
				if (je instanceof ICompilationUnit)
					break;
				je= je.getParent();
			}

			// revert the path
			int n= args.size();
			String[] path= new String[n];
			for (int i= 0; i < n; i++)
				path[i]= args.get(n-1-i);

			return path;
		}
		return null;
	}
}
