/*******************************************************************************
 * 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
 *
 * This is an implementation of an early-draft specification developed under the Java
 * Community Process (JCP) and is made available for testing and evaluation purposes
 * only. The code is not compatible with any specification of the JCP.
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Terry Parker <tparker@google.com> - [performance] Low hit rates in JavaModel caches - https://bugs.eclipse.org/421165
 *******************************************************************************/
package org.eclipse.jdt.internal.core;

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

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.internal.core.util.MementoTokenizer;
import org.eclipse.jdt.internal.core.util.Messages;

/**
 * Implementation of {@link IJavaModel}. The Java Model maintains a cache of active
 * {@link IJavaProject}s in a workspace. A Java Model is specific to a workspace.
 * To retrieve a workspace's model, use the
 * {@link IJavaElement#getJavaModel() #getJavaModel()} method.
 *
 * @see IJavaModel
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public class JavaModel extends Openable implements IJavaModel {

/**
 * Constructs a new Java Model on the given workspace.
 * Note that only one instance of JavaModel handle should ever be created.
 * One should only indirect through JavaModelManager#getJavaModel() to get
 * access to it.
 *
 * @exception Error if called more than once
 */
protected JavaModel() throws Error {
	super(null);
}
protected boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource)	/*throws JavaModelException*/ {

	// determine my children
	IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
	int length = projects.length;
	IJavaElement[] children = new IJavaElement[length];
	int index = 0;
	for (int i = 0; i < length; i++) {
		IProject project = projects[i];
		if (JavaProject.hasJavaNature(project)) {
			children[index++] = getJavaProject(project);
		}
	}
	if (index < length)
		System.arraycopy(children, 0, children = new IJavaElement[index], 0, index);
	info.setChildren(children);

	newElements.put(this, info);

	return true;
}
/*
 * @see IJavaModel
 */
public boolean contains(IResource resource) {
	switch (resource.getType()) {
		case IResource.ROOT:
		case IResource.PROJECT:
			return true;
	}
	// file or folder
	IJavaProject[] projects;
	try {
		projects = getJavaProjects();
	} catch (JavaModelException e) {
		return false;
	}
	for (int i = 0, length = projects.length; i < length; i++) {
		JavaProject project = (JavaProject)projects[i];
		if (!project.contains(resource)) {
			return false;
		}
	}
	return true;
}
/**
 * @see IJavaModel
 */
public void copy(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException {
	if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
		runOperation(new CopyResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
	} else {
		runOperation(new CopyElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
	}
}
/**
 * Returns a new element info for this element.
 */
protected Object createElementInfo() {
	return new JavaModelInfo();
}

/**
 * @see IJavaModel
 */
public void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) throws JavaModelException {
	if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
		new DeleteResourceElementsOperation(elements, force).runOperation(monitor);
	} else {
		new DeleteElementsOperation(elements, force).runOperation(monitor);
	}
}
public boolean equals(Object o) {
	if (!(o instanceof JavaModel)) return false;
	return super.equals(o);
}
/**
 * @see IJavaElement
 */
public int getElementType() {
	return JAVA_MODEL;
}

/*
 * @see JavaElement
 */
public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner) {
	switch (token.charAt(0)) {
		case JEM_JAVAPROJECT:
			if (!memento.hasMoreTokens()) return this;
			String projectName = memento.nextToken();
			JavaElement project = (JavaElement)getJavaProject(projectName);
			return project.getHandleFromMemento(memento, owner);
	}
	return null;
}
/**
 * @see JavaElement#getHandleMemento(StringBuffer)
 */
protected void getHandleMemento(StringBuffer buff) {
	buff.append(getElementName());
}
/**
 * Returns the <code>char</code> that marks the start of this handles
 * contribution to a memento.
 */
protected char getHandleMementoDelimiter(){
	Assert.isTrue(false, "Should not be called"); //$NON-NLS-1$
	return 0;
}
/**
 * @see IJavaModel
 */
public IJavaProject getJavaProject(String projectName) {
	return new JavaProject(ResourcesPlugin.getWorkspace().getRoot().getProject(projectName), this);
}
/**
 * Returns the active Java project associated with the specified
 * resource, or <code>null</code> if no Java project yet exists
 * for the resource.
 *
 * @exception IllegalArgumentException if the given resource
 * is not one of an IProject, IFolder, or IFile.
 */
public IJavaProject getJavaProject(IResource resource) {
	switch(resource.getType()){
		case IResource.FOLDER:
			return new JavaProject(((IFolder)resource).getProject(), this);
		case IResource.FILE:
			return new JavaProject(((IFile)resource).getProject(), this);
		case IResource.PROJECT:
			return new JavaProject((IProject)resource, this);
		default:
			throw new IllegalArgumentException(Messages.element_invalidResourceForProject);
	}
}
/**
 * @see IJavaModel
 */
public IJavaProject[] getJavaProjects() throws JavaModelException {
	ArrayList list = getChildrenOfType(JAVA_PROJECT);
	IJavaProject[] array= new IJavaProject[list.size()];
	list.toArray(array);
	return array;

}
/**
 * @see IJavaModel
 */
public Object[] getNonJavaResources() throws JavaModelException {
		return ((JavaModelInfo) getElementInfo()).getNonJavaResources();
}

/*
 * @see IJavaElement
 */
public IPath getPath() {
	return Path.ROOT;
}
/*
 * @see IJavaElement
 */
public IResource resource(PackageFragmentRoot root) {
	return ResourcesPlugin.getWorkspace().getRoot();
}
/**
 * @see IOpenable
 */
public IResource getUnderlyingResource() {
	return null;
}
/**
 * Returns the workbench associated with this object.
 */
public IWorkspace getWorkspace() {
	return ResourcesPlugin.getWorkspace();
}

/**
 * @see IJavaModel
 */
public void move(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException {
	if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
		runOperation(new MoveResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
	} else {
		runOperation(new MoveElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
	}
}

/**
 * @see IJavaModel#refreshExternalArchives(IJavaElement[], IProgressMonitor)
 */
public void refreshExternalArchives(IJavaElement[] elementsScope, IProgressMonitor monitor) throws JavaModelException {
	if (elementsScope == null){
		elementsScope = new IJavaElement[] { this };
	}
	JavaModelManager.getJavaModelManager().getDeltaProcessor().checkExternalArchiveChanges(elementsScope, monitor);
}

/**
 * @see IJavaModel
 */
public void rename(IJavaElement[] elements, IJavaElement[] destinations, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException {
	MultiOperation op;
	if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
		op = new RenameResourceElementsOperation(elements, destinations, renamings, force);
	} else {
		op = new RenameElementsOperation(elements, destinations, renamings, force);
	}

	op.runOperation(monitor);
}
/**
 * Configures and runs the <code>MultiOperation</code>.
 */
protected void runOperation(MultiOperation op, IJavaElement[] elements, IJavaElement[] siblings, String[] renamings, IProgressMonitor monitor) throws JavaModelException {
	op.setRenamings(renamings);
	if (siblings != null) {
		for (int i = 0; i < elements.length; i++) {
			op.setInsertBefore(elements[i], siblings[i]);
		}
	}
	op.runOperation(monitor);
}
/**
 * @private Debugging purposes
 */
protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
	buffer.append(tabString(tab));
	buffer.append("Java Model"); //$NON-NLS-1$
	if (info == null) {
		buffer.append(" (not open)"); //$NON-NLS-1$
	}
}

/**
 * Helper method - for the provided {@link IPath}, returns:
 * <ul>
 * <li>If the path corresponds to an internal file or folder, the {@link IResource} for that resource
 * <li>If the path corresponds to an external folder linked through {@link ExternalFoldersManager},
 * the {@link IFolder} for that folder
 * <li>If the path corresponds to an external library archive, the {@link File} for that archive
 * <li>Can return <code>null</code> if <code>checkResourceExistence</code> is <code>true</code>
 * and the entity referred to by the path does not exist on the file system
 * </ul>
 * Internal items must be referred to using container-relative paths.
 */
public static Object getTarget(IPath path, boolean checkResourceExistence) {
	Object target = getWorkspaceTarget(path); // Implicitly checks resource existence
	if (target != null)
		return target;
	return getExternalTarget(path, checkResourceExistence);
}

/**
 * Helper method - returns the {@link IResource} corresponding to the provided {@link IPath},
 * or <code>null</code> if no such resource exists.
 */
public static IResource getWorkspaceTarget(IPath path) {
	if (path == null || path.getDevice() != null)
		return null;
	IWorkspace workspace = ResourcesPlugin.getWorkspace();
	if (workspace == null)
		return null;
	return workspace.getRoot().findMember(path);
}

/**
 * Helper method - returns either the linked {@link IFolder} or the {@link File} corresponding
 * to the provided {@link IPath}. If <code>checkResourceExistence</code> is <code>false</code>,
 * then the IFolder or File object is always returned, otherwise <code>null</code> is returned
 * if it does not exist on the file system.
 */
public static Object getExternalTarget(IPath path, boolean checkResourceExistence) {
	if (path == null)
		return null;
	ExternalFoldersManager externalFoldersManager = JavaModelManager.getExternalManager();
	Object linkedFolder = externalFoldersManager.getFolder(path);
	if (linkedFolder != null) {
		if (checkResourceExistence) {
			// check if external folder is present
			File externalFile = new File(path.toOSString());
			if (!externalFile.isDirectory()) {
				return null;
			}
		}
		return linkedFolder;
	}
	File externalFile = new File(path.toOSString());
	if (!checkResourceExistence) {
		return externalFile;
	} else if (isExternalFile(path)) {
		return externalFile;
	}
	return null;
}

/**
 * Helper method - returns whether an object is a file (i.e., it returns <code>true</code>
 * to {@link File#isFile()}.
 */
public static boolean isFile(Object target) {
	if (target instanceof File) {
		IPath path = Path.fromOSString(((File) target).getPath());
		return isExternalFile(path);
	}
	return false;
}

public static boolean isJimage(File file) {
	return JavaModelManager.isJrt(file.getPath());
}

/**
 * Returns whether the provided path is an external file, checking and updating the
 * JavaModelManager's external file cache.
 */
static private boolean isExternalFile(IPath path) {
	if (JavaModelManager.getJavaModelManager().isExternalFile(path)) {
		return true;
	}
	if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
		System.out.println("(" + Thread.currentThread() + ") [JavaModel.isExternalFile(...)] Checking existence of " + path.toString()); //$NON-NLS-1$ //$NON-NLS-2$
	}
	boolean isFile = path.toFile().isFile();
	if (isFile) {
		JavaModelManager.getJavaModelManager().addExternalFile(path);
	}
	return isFile;
}

/**
 * Helper method - returns the {@link File} item if <code>target</code> is a file (i.e., the target
 * returns <code>true</code> to {@link File#isFile()}. Otherwise returns <code>null</code>.
 */
public static File getFile(Object target) {
	return isFile(target) ? (File) target : null;
}

protected IStatus validateExistence(IResource underlyingResource) {
	// Java model always exists
	return JavaModelStatus.VERIFIED_OK;
}
}
