/*******************************************************************************
 * Copyright (c) 2005, 2009 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 com.sun.jdi.VMDisconnectedException;

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

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.core.resources.IResource;

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.TypeDeclarationStatement;

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.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;

/**
 * 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.JLS3);
                		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(TypeDeclarationStatement 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;
    }
}
