/*******************************************************************************
 * Copyright (c) 2005, 2006 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.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 correponding Java model type or <code>null</code>
     * @exception CoreException if an exception occurrs 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 correponding Java model type or <code>null</code>
     * @exception CoreException if an exception occurrs 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 associcated 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
     * @throws CoreException
     */
    private static IType resolveType(String qualifiedName, IJavaElement javaElement) throws CoreException {
    	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];
                try {
                    Integer.parseInt(innerTypeName);
                    return type;
                } catch (NumberFormatException e) {
                }
                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
     */
    private static IJavaElement resolveJavaElement(Object object, ILaunch launch) throws CoreException {
    	Object sourceElement = resolveSourceElement(object, launch);
        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 comiplation unit containing the given fully qualified name in the 
     * specified project. All reqistered 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;
    }
}
