/*******************************************************************************
 * Copyright (c) 2017, Red Hat Inc. 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 (from JavaDebugHover)
 *     Mickael Istria (Red Hat Inc.) - 521960 adaptation from JavaDebugHover
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.ui;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;

import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICodeAssist;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.ILocalVariable;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
import org.eclipse.jdt.core.dom.ThisExpression;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaReferenceType;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.core.IJavaValue;
import org.eclipse.jdt.debug.core.IJavaVariable;
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIPlaceholderVariable;
import org.eclipse.jdt.internal.debug.eval.ast.engine.ASTEvaluationEngine;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.SharedASTProvider;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;

public class SelectionToIVaraibleAdapterFactory implements IAdapterFactory {

	@Override
	public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
		if (!(adaptableObject instanceof TextSelection)) {
			return null;
		}
		if (!adapterType.isAssignableFrom(IVariable.class)) {
			return null;
		}
		TextSelection selection = (TextSelection) adaptableObject;
		IDocument document = null;
		try {
			Field documentField = TextSelection.class.getDeclaredField("fDocument"); //$NON-NLS-1$
			documentField.setAccessible(true);
			document = (Document) documentField.get(selection);
		}
		catch (Exception e) {
			JavaPlugin.log(e);
		}
		if (document == null) {
			return null;
		}
		return adapterType.cast(getVariable(document, new Region(selection.getOffset(), selection.getLength())));
	}

	@Override
	public Class<?>[] getAdapterList() {
		return new Class<?>[] { IVariable.class };
	}

	/**
	 * Returns the stack frame in which to search for variables, or <code>null</code> if none.
	 *
	 * @return the stack frame in which to search for variables, or <code>null</code> if none
	 */
	protected IJavaStackFrame getFrame() {
		IAdaptable adaptable = DebugUITools.getDebugContext();
		if (adaptable != null) {
			return adaptable.getAdapter(IJavaStackFrame.class);
		}
		return null;
	}

	private IVariable getVariable(IDocument document, IRegion region) {
		IJavaStackFrame frame = getFrame();
		if (frame == null) {
			return null;
		}
		String variableName = null;
		try {
			variableName = document.get(region.getOffset(), region.getLength());
		}
		catch (BadLocationException e) {
			return null;
		}
		if (variableName.equals("this")) { //$NON-NLS-1$
			try {
				IJavaVariable variable = frame.findVariable(variableName);
				if (variable != null) {
					return variable;
				}
			}
			catch (DebugException e) {
				JavaPlugin.log(e);
				return null;
			}
		}
		ICodeAssist codeAssist = getCodeAssist(document);
		if (codeAssist == null) {
			return findLocalVariable(frame, variableName);
		}

		IJavaElement[] resolve = null;
		try {
			resolve = codeAssist.codeSelect(region.getOffset(), 0);
		}
		catch (JavaModelException e1) {
			resolve = new IJavaElement[0];
		}
		try {
			for (int i = 0; i < resolve.length; i++) {
				IJavaElement javaElement = resolve[i];
				if (javaElement instanceof IField) {
					IField field = (IField) javaElement;
					IJavaVariable variable = null;
					IJavaDebugTarget debugTarget = (IJavaDebugTarget) frame.getDebugTarget();
					if (Flags.isStatic(field.getFlags())) {
						IJavaType[] javaTypes = debugTarget.getJavaTypes(field.getDeclaringType().getFullyQualifiedName());
						if (javaTypes != null) {
							for (int j = 0; j < javaTypes.length; j++) {
								IJavaType type = javaTypes[j];
								if (type instanceof IJavaReferenceType) {
									IJavaReferenceType referenceType = (IJavaReferenceType) type;
									variable = referenceType.getField(field.getElementName());
								}
								if (variable != null) {
									break;
								}
							}
						}
						if (variable == null) {
							// the class is not loaded yet, but may be an in-lined primitive constant
							Object constant = field.getConstant();
							if (constant != null) {
								IJavaValue value = null;
								if (constant instanceof Integer) {
									value = debugTarget.newValue(((Integer) constant).intValue());
								} else if (constant instanceof Byte) {
									value = debugTarget.newValue(((Byte) constant).byteValue());
								} else if (constant instanceof Boolean) {
									value = debugTarget.newValue(((Boolean) constant).booleanValue());
								} else if (constant instanceof Character) {
									value = debugTarget.newValue(((Character) constant).charValue());
								} else if (constant instanceof Double) {
									value = debugTarget.newValue(((Double) constant).doubleValue());
								} else if (constant instanceof Float) {
									value = debugTarget.newValue(((Float) constant).floatValue());
								} else if (constant instanceof Long) {
									value = debugTarget.newValue(((Long) constant).longValue());
								} else if (constant instanceof Short) {
									value = debugTarget.newValue(((Short) constant).shortValue());
								} else if (constant instanceof String) {
									value = debugTarget.newValue((String) constant);
								}
								if (value != null) {
									variable = new JDIPlaceholderVariable(field.getElementName(), value);
								}
							}
							if (variable == null) {
								return null; // class not loaded yet and not a constant
							}
						}
					} else {
						if (!frame.isStatic() && !frame.isNative()) {
							// ensure that we only resolve a field access on 'this':
							if (!(codeAssist instanceof ITypeRoot)) {
								return null;
							}
							ITypeRoot typeRoot = (ITypeRoot) codeAssist;
							ASTNode root = SharedASTProvider.getAST(typeRoot, SharedASTProvider.WAIT_NO, null);
							if (root == null) {
								ASTParser parser = ASTParser.newParser(AST.JLS9);
								parser.setSource(typeRoot);
								parser.setFocalPosition(region.getOffset());
								root = parser.createAST(null);
							}
							ASTNode node = NodeFinder.perform(root, region.getOffset(), region.getLength());
							if (node == null) {
								return null;
							}
							StructuralPropertyDescriptor locationInParent = node.getLocationInParent();
							if (locationInParent == FieldAccess.NAME_PROPERTY) {
								FieldAccess fieldAccess = (FieldAccess) node.getParent();
								if (!(fieldAccess.getExpression() instanceof ThisExpression)) {
									return null;
								}
							} else if (locationInParent == QualifiedName.NAME_PROPERTY) {
								return null;
							}

							String typeSignature = Signature.createTypeSignature(field.getDeclaringType().getFullyQualifiedName(), true);
							typeSignature = typeSignature.replace('.', '/');
							IJavaObject ths = frame.getThis();
							if (ths != null) {
								variable = ths.getField(field.getElementName(), typeSignature);
							}
						}
					}
					if (variable != null) {
						return variable;
					}
					break;
				}
				if (javaElement instanceof ILocalVariable) {
					ILocalVariable var = (ILocalVariable) javaElement;
					IJavaElement parent = var.getParent();
					while (!(parent instanceof IMethod) && parent != null) {
						parent = parent.getParent();
					}
					if (parent instanceof IMethod) {
						IMethod method = (IMethod) parent;
						boolean equal = false;
						if (method.isBinary()) {
							// compare resolved signatures
							if (method.getSignature().equals(frame.getSignature())) {
								equal = true;
							}
						} else {
							// compare unresolved signatures

							// Frames in classes with generics have declaringTypeName like class<V>
							// We must get rid of this '<V>' for proper comparison
							String frameDeclaringTypeName = frame.getDeclaringTypeName();
							int genericPartOffset = frameDeclaringTypeName.indexOf('<');
							if (genericPartOffset != -1) {
								frameDeclaringTypeName = frameDeclaringTypeName.substring(0, genericPartOffset);
							}

							if (((frame.isConstructor() && method.isConstructor()) || frame.getMethodName().equals(method.getElementName()))
									&& frameDeclaringTypeName.endsWith(method.getDeclaringType().getElementName())
									&& frame.getArgumentTypeNames().size() == method.getNumberOfParameters()) {
								equal = true;
							} else { // Finding variables in anonymous class
								int index = frame.getDeclaringTypeName().indexOf('$');
								if (index > 0) {
									String name = frame.getDeclaringTypeName().substring(index + 1);
									try {
										Integer.getInteger(name);
										return findLocalVariable(frame, ASTEvaluationEngine.ANONYMOUS_VAR_PREFIX + var.getElementName());
									}
									catch (NumberFormatException ex) {
									}
								}
							}
						}
						// find variable if equal or method is a Lambda Method
						if (equal || method.isLambdaMethod()) {
							return findLocalVariable(frame, var.getElementName());
						}
					}
					break;
				}
			}
		}
		catch (CoreException e) {
			JDIDebugPlugin.log(e);
		}
		return null;
	}

	private ICodeAssist getCodeAssist(IEditorInput input) {
		if (input == null) {
			return null;
		}
		Object element = JavaUI.getWorkingCopyManager().getWorkingCopy(input);
		if (element == null) {
			element = input.getAdapter(IClassFile.class);
		}
		if (element instanceof ICodeAssist) {
			return ((ICodeAssist) element);
		}
		return null;
	}

	private ICodeAssist getCodeAssist(IDocument document) {
		ITextFileBuffer textFileBuffer = ITextFileBufferManager.DEFAULT.getTextFileBuffer(document);
		if (textFileBuffer == null) {
			return null;
		}
		Optional<ICodeAssist> codeAssist = Arrays.stream(PlatformUI.getWorkbench().getWorkbenchWindows())
				.flatMap(window -> Arrays.stream(window.getPages()))
				.flatMap(page -> Arrays.stream(page.getEditorReferences())).filter(editor -> {
					try {
						return matches(editor.getEditorInput(), textFileBuffer);
					}
					catch (PartInitException e1) {
						JavaPlugin.log(e1);
						return false;
					}
				})
				.filter(editor -> editor.getEditor(false) != null) // editor that are initialized only
				.map(ref -> {
					try {
						return ref.getEditorInput();
					}
					catch (PartInitException e) {
						JavaPlugin.log(e);
						return null;
					}
				}).map(this::getCodeAssist)
				.filter(Objects::nonNull)
				.distinct()
				.findAny();
		if (codeAssist.isPresent()) {
			return codeAssist.get();
		}
		return null;
	}

	private boolean matches(IEditorInput input, ITextFileBuffer textFileBuffer) {
		if (input instanceof IFileEditorInput && textFileBuffer.getLocation().equals(((IFileEditorInput) input).getFile().getFullPath())) {
			return true;
		}
		// TODO maybe map URIs and other kinds of input
		return false;
	}

	/**
	 * Returns a local variable in the given frame based on the the given name or <code>null</code> if none.
	 *
	 * @return local variable or <code>null</code>
	 */
	private IVariable findLocalVariable(IJavaStackFrame frame, String variableName) {
		if (frame != null) {
			try {
				return frame.findVariable(variableName);
			}
			catch (DebugException x) {
				if (x.getStatus().getCode() != IJavaThread.ERR_THREAD_NOT_SUSPENDED) {
					JDIDebugUIPlugin.log(x);
				}
			}
		}
		return null;
	}


}
