/*******************************************************************************
 * Copyright (c) 2005, 2011 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.debug.core;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.TypeDeclaration;
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 com.sun.jdi.VMDisconnectedException;

/**
 * A Utilities class.
 * 
 * @since 3.2
 */
public class JavaDebugUtils {

    /**
     * Resolves and returns a type from the Java model that corresponds to the
     * declaring type of the given stack frame, or <code>null</code> if none.
     *  
     * @param frame frame to resolve declaring type for
     * @return corresponding Java model type or <code>null</code>
     * @exception CoreException if an exception occurs during the resolution
     * @since 3.2
     */
    public static IType resolveDeclaringType(IJavaStackFrame frame) throws CoreException {
        IJavaElement javaElement = resolveJavaElement(frame, frame.getLaunch());
        if (javaElement != null) {
        	return resolveType(frame.getDeclaringTypeName(), javaElement);
        }
        return null;
    }
    
    /**
     * Resolves and returns a type from the Java model that corresponds to the
     * type of the given value, or <code>null</code> if none.
     *  
     * @param value value to resolve type for
     * @return corresponding Java model type or <code>null</code>
     * @exception CoreException if an exception occurs during the resolution
     */
    public static IType resolveType(IJavaValue value) throws CoreException {
        IJavaElement javaElement = resolveJavaElement(value, value.getLaunch());
        if (javaElement != null) {
        	return resolveType(value.getJavaType().getName(), javaElement);
        }
        return null;
    }   
    
    /**
     * Resolves and returns the Java model type associated with the given
     * Java debug type, or <code>null</code> if none.
     * 
     * @param type Java debug model type
     * @return Java model type or <code>null</code>
     * @throws CoreException
     */
    public static IType resolveType(IJavaType type) throws CoreException {
    	IJavaElement element = resolveJavaElement(type, type.getLaunch());
    	if (element != null ) {
    		return resolveType(type.getName(), element);
    	}
    	return null;
    }    
    
	/**
	 * Returns the source name associated with the given object, or <code>null</code>
	 * if none.
	 * 
	 * @param object an object with an <code>IJavaStackFrame</code> adapter, an IJavaValue
	 *  or an IJavaType 
	 * @return the source name associated with the given object, or <code>null</code>
	 * if none
	 * @exception CoreException if unable to retrieve the source name
	 */
	public static String getSourceName(Object object) throws CoreException {
		if (object instanceof String) {
			// assume it's a file name
			return (String)object;
		}
		IJavaStackFrame frame = null;
		if (object instanceof IAdaptable) {
			frame = (IJavaStackFrame) ((IAdaptable)object).getAdapter(IJavaStackFrame.class);
		}
		String typeName = null;
		try {
			if (frame != null) {
				if (frame.isObsolete()) {
					return null;
				}
				String sourceName = frame.getSourcePath();
				// TODO: this may break fix to bug 21518
				if (sourceName == null) {
					// no debug attributes, guess at source name
					typeName = frame.getDeclaringTypeName();
				} else {
					return sourceName;
				}
			} else {
				if (object instanceof IJavaValue) {
					// look at its type
					object = ((IJavaValue)object).getJavaType();
				}
				if (object instanceof IJavaReferenceType) {
					IJavaReferenceType refType = (IJavaReferenceType)object;
					String[] sourcePaths = refType.getSourcePaths(null);
					if (sourcePaths != null && sourcePaths.length > 0) {
						return sourcePaths[0];
					}
				}
				if (object instanceof IJavaType) {
					typeName = ((IJavaType)object).getName();
				}
			}
		} catch (DebugException e) {
			int code = e.getStatus().getCode();
            if (code == IJavaThread.ERR_THREAD_NOT_SUSPENDED || code == IJavaStackFrame.ERR_INVALID_STACK_FRAME ||
					e.getStatus().getException() instanceof VMDisconnectedException) {
				return null;
			}
			throw e;
		}
		if (typeName != null) {
			return generateSourceName(typeName);
		}
		return null;
	}    
    
	/**
	 * Generates and returns a source file path based on a qualified type name.
	 * For example, when <code>java.lang.String</code> is provided,
	 * the returned source name is <code>java/lang/String.java</code>.
	 * 
	 * @param qualifiedTypeName fully qualified type name that may contain inner types
	 *  denoted with <code>$</code> character
	 * @return a source file path corresponding to the type name
	 */
	public static String generateSourceName(String qualifiedTypeName) {
		int index = qualifiedTypeName.lastIndexOf('.');
		if (index < 0) {
			index = 0;
		}
		qualifiedTypeName = qualifiedTypeName.replace('.', File.separatorChar);
		index = qualifiedTypeName.indexOf('$');
		if (index >= 0) {
			qualifiedTypeName = qualifiedTypeName.substring(0, index);
		}
		if (qualifiedTypeName.length() == 0) {
			// likely a proxy class (see bug 40815)
			qualifiedTypeName = null;
		} else {
			qualifiedTypeName = qualifiedTypeName + ".java"; //$NON-NLS-1$
		}
		return qualifiedTypeName;
	}    
    
    /**
     * Resolves the type corresponding to the given name contained in the given top-level
     * Java element (class file, compilation unit, or type).
     * 
     * @param qualifiedName fully qualified type name
     * @param javaElement java element containing the type
     * @return type
     */
    private static IType resolveType(final String qualifiedName, IJavaElement javaElement) {
    	IType type = null;
        String[] typeNames = getNestedTypeNames(qualifiedName);
        if (javaElement instanceof IClassFile) {
            type = ((IClassFile)javaElement).getType();
        } else if (javaElement instanceof ICompilationUnit) {
            type = ((ICompilationUnit)javaElement).getType(typeNames[0]);
        } else if (javaElement instanceof IType) {
            type = (IType)javaElement;
        }
        if (type != null) {
            for (int i = 1; i < typeNames.length; i++) {
                String innerTypeName= typeNames[i];
                
                class ResultException extends RuntimeException {
					private static final long serialVersionUID= 1L;
					private final IType fResult;
                	public ResultException(IType result) {
                		fResult= result;
                	}
                }
                if (innerTypeName.length() > 0) {
                	try {
                		Integer.parseInt(innerTypeName.substring(0, 1)); // throws NFE if not an integer
                		
                		// perform expensive lookup for anonymous types:
                		ASTParser parser = ASTParser.newParser(AST.JLS4);
                		parser.setResolveBindings(true);
                		parser.setSource(type.getTypeRoot());
                		CompilationUnit cu = (CompilationUnit) parser.createAST(null);
                		cu.accept(new ASTVisitor(false) {
                			public boolean visit(AnonymousClassDeclaration node) {
                				ITypeBinding binding = node.resolveBinding();
                				if (binding == null)
                					return false;
                				if (qualifiedName.equals(binding.getBinaryName()))
                					throw new ResultException((IType) binding.getJavaElement());
                				return true;
                			}
                			public boolean visit(TypeDeclaration node) {
                				ITypeBinding binding = node.resolveBinding();
                				if (binding == null)
                					return false;
                				if (qualifiedName.equals(binding.getBinaryName()))
                					throw new ResultException((IType) binding.getJavaElement());
                				return true;
                			}
                		});
                		return type; // return enclosing type if exact type not found
                	} catch (NumberFormatException e) {
	                	// normal nested type, continue
	                } catch (IllegalStateException e) {
	                	return type; // binary class without source
	                } catch (ResultException e) {
	                	return e.fResult;
	                }
                }
                type = type.getType(innerTypeName);
            }
        }
        return type;     	
    }
    
    /**
     * Returns the Java element corresponding to the given object or <code>null</code>
     * if none, in the context of the given launch.
     * 
     * @param launch provides source locator
     * @param object object to resolve Java model element for
     * @return corresponding Java element or <code>null</code>
     * @throws CoreException
     */
    public static IJavaElement resolveJavaElement(Object object, ILaunch launch) throws CoreException {
    	Object sourceElement = resolveSourceElement(object, launch);
        return getJavaElement(sourceElement);
    }

	/**
	 * Returns the {@link IJavaElement} associated with the given source element or <code>null</code>
	 * if none.
	 * 
	 * @param sourceElement a java element, object that adapts to a java element, or a resource
	 * @return corresponding {@link IJavaElement} or <code>null</code>
	 * @since 3.4.0
	 */
	public static IJavaElement getJavaElement(Object sourceElement) {
		IJavaElement javaElement = null;
        if (sourceElement instanceof IJavaElement) {
            javaElement = (IJavaElement) sourceElement;
        } else if (sourceElement instanceof IAdaptable) {
            javaElement = (IJavaElement) ((IAdaptable)sourceElement).getAdapter(IJavaElement.class);
        }
        if (javaElement == null && sourceElement instanceof IResource) {
            javaElement= JavaCore.create((IResource)sourceElement);
        }
        if (javaElement == null) {
            return null;
        }
        if (!javaElement.exists()) {
            return null;
        }
        return javaElement;
	}  
    
    /**
     * Returns the source element corresponding to the given object or <code>null</code>
     * if none, in the context of the given launch.
     * 
     * @param launch provides source locator
     * @param object object to resolve source element for
     * @return corresponding source element or <code>null</code>
     * @throws CoreException
     */
    public static Object resolveSourceElement(Object object, ILaunch launch) throws CoreException {
    	ISourceLocator sourceLocator = launch.getSourceLocator();
		if (sourceLocator instanceof ISourceLookupDirector) {
			ISourceLookupDirector director = (ISourceLookupDirector) sourceLocator;
			Object[] objects = director.findSourceElements(object);
			if (objects.length > 0) {
				 return objects[0];
			}
		}
		return null;
    }      

    /**
     * Returns an array of simple type names that are
     * part of the given type's qualified name. For
     * example, if the given name is <code>x.y.A$B</code>,
     * an array with <code>["A", "B"]</code> is returned.
     * 
     * @param typeName fully qualified type name
     * @return array of nested type names
     */
    private static String[] getNestedTypeNames(String typeName) {
        int index = typeName.lastIndexOf('.');
        if (index >= 0) {
            typeName= typeName.substring(index + 1);
        }
        index = typeName.indexOf('$');
        List list = new ArrayList(1);
        while (index >= 0) {
            list.add(typeName.substring(0, index));
            typeName = typeName.substring(index + 1);
            index = typeName.indexOf('$');
        }
        list.add(typeName);
        return (String[])list.toArray(new String[list.size()]); 
    } 
    
    /**
     * Returns the class file or compilation unit containing the given fully qualified name in the 
     * specified project. All registered java like file extensions are considered.
     * 
     * @param qualifiedTypeName fully qualified type name
     * @param project project to search in
     * @return class file or compilation unit or <code>null</code>
     */
    public static IJavaElement findElement(String qualifiedTypeName, IJavaProject project) throws CoreException{
    	String[] javaLikeExtensions = JavaCore.getJavaLikeExtensions();
    	String path = qualifiedTypeName;
		int pos = path.indexOf('$');
		if (pos != -1) {
			path= path.substring(0, pos);
		}
		path = path.replace('.', IPath.SEPARATOR);
		path += "."; //$NON-NLS-1$    	
    	for (int i = 0; i < javaLikeExtensions.length; i++) {
			String ext = javaLikeExtensions[i];
			IJavaElement element = project.findElement(new Path(path + ext));
			if (element != null) {
				return element;
			}
		}
    	return null;
    }
}
