/*******************************************************************************
 * Copyright (c) 2005, 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
 *
 *******************************************************************************/
package org.eclipse.dltk.internal.corext.refactoring;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.dltk.core.IField;
import org.eclipse.dltk.core.IMethod;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptFolder;
import org.eclipse.dltk.core.IScriptModel;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.ScriptModelUtil;
import org.eclipse.dltk.internal.corext.refactoring.reorg.ReorgPolicyFactory;
import org.eclipse.dltk.internal.corext.refactoring.reorg.ReorgUtils;
import org.eclipse.dltk.internal.ui.editor.ModelTextSelection;
import org.eclipse.jface.viewers.IStructuredSelection;

/**
 * Helper class to detect whether a certain refactoring can be enabled on a
 * selection.
 * <p>
 * This class has been introduced to decouple actions from the refactoring code,
 * in order not to eagerly load refactoring classes during action
 * initialization.
 * </p>
 * 
 * 
 */
public final class RefactoringAvailabilityTester {

	public static IType getDeclaringType(IModelElement element) {
		if (element == null)
			return null;
		if (!(element instanceof IType))
			element = element.getAncestor(IModelElement.TYPE);
		return (IType) element;
	}

	public static IModelElement[] getScriptElements(final Object[] elements) {
		List<IModelElement> result = new ArrayList<IModelElement>();
		for (int index = 0; index < elements.length; index++) {
			if (elements[index] instanceof IModelElement)
				result.add((IModelElement) elements[index]);
		}
		return result.toArray(new IModelElement[result.size()]);
	}

	public static IResource[] getResources(final Object[] elements) {
		List<IResource> result = new ArrayList<IResource>();
		for (int index = 0; index < elements.length; index++) {
			if (elements[index] instanceof IResource)
				result.add((IResource) elements[index]);
		}
		return result.toArray(new IResource[result.size()]);
	}

	public static boolean isRenameElementAvailable(IModelElement element)
			throws CoreException {
		switch (element.getElementType()) {
		case IModelElement.SCRIPT_PROJECT:
			return isRenameAvailable((IScriptProject) element);
		case IModelElement.PROJECT_FRAGMENT:
			return isRenameAvailable((IProjectFragment) element);
		case IModelElement.SOURCE_MODULE:
			return isRenameAvailable((ISourceModule) element);
		case IModelElement.TYPE:
			return isRenameAvailable((IType) element);
		case IModelElement.METHOD:
			final IMethod method = (IMethod) element;
			if (method.isConstructor())
				return isRenameAvailable(method.getDeclaringType());
			else
				return isRenameAvailable(method);
		case IModelElement.FIELD:
			final IField field = (IField) element;
			return isRenameFieldAvailable(field);
		}
		return false;
	}

	public static boolean isRenameAvailable(final ISourceModule unit) {
		if (unit == null)
			return false;
		if (!unit.exists())
			return false;
		if (!ScriptModelUtil.isPrimary(unit))
			return false;
		if (unit.isReadOnly())
			return false;
		return true;
	}

	public static boolean isRenameAvailable(final IScriptProject project)
			throws ModelException {
		if (project == null)
			return false;
		if (!Checks.isAvailable(project))
			return false;
		if (!project.isConsistent())
			return false;
		return true;
	}

	public static boolean isRenameAvailable(final IMethod method)
			throws CoreException {
		if (method == null)
			return false;
		if (!Checks.isAvailable(method))
			return false;
		if (method.isConstructor())
			return false;
		return true;
	}

	public static boolean isRenameAvailable(final IScriptFolder fragment)
			throws ModelException {
		if (fragment == null)
			return false;
		if (!Checks.isAvailable(fragment))
			return false;
		if (fragment.isRootFolder())
			return false;
		return true;
	}

	public static boolean isRenameAvailable(final IProjectFragment root)
			throws ModelException {
		if (root == null)
			return false;
		if (!Checks.isAvailable(root))
			return false;
		if (root.isArchive())
			return false;
		if (root.isExternal())
			return false;
		if (!root.isConsistent())
			return false;
		if (root.getResource() instanceof IProject)
			return false;
		return true;
	}

	public static boolean isRenameAvailable(final IResource resource) {
		if (resource == null)
			return false;
		if (!resource.exists())
			return false;
		if (!resource.isAccessible())
			return false;
		return true;
	}

	public static boolean isRenameAvailable(final IType type)
			throws ModelException {
		if (type == null)
			return false;
		if (!Checks.isAvailable(type))
			return false;
		return true;
	}

	public static boolean isRenameFieldAvailable(final IField field)
			throws ModelException {
		return Checks.isAvailable(field);
	}

	public static boolean isReplaceInvocationsAvailable(IMethod method)
			throws ModelException {
		if (method == null)
			return false;
		if (!method.exists())
			return false;
		if (method.isConstructor())
			return false;
		return true;
	}

	public static boolean isDeleteAvailable(final IModelElement element)
			throws ModelException {
		if (!element.exists())
			return false;
		if (element instanceof IScriptModel
				|| element instanceof IScriptProject)
			return false;
		if (element.getParent() != null && element.getParent().isReadOnly())
			return false;
		if (element instanceof IProjectFragment) {
			IProjectFragment root = (IProjectFragment) element;
			if (root.isExternal() || Checks.isBuildpathDelete(root)) // TODO
				// rename
				// isClasspathDelete
				return false;
		}
		if (element.getResource() == null
				&& !RefactoringAvailabilityTester.isWorkingCopyElement(element))
			return false;
		// if (element instanceof IMember && ((IMember) element).isBinary())
		// return false;
		if (ReorgUtils.isDeletedFromEditor(element))
			return false;
		return true;
	}

	public static boolean isDeleteAvailable(final IResource resource) {
		if (!resource.exists() || resource.isPhantom())
			return false;
		if (resource.getType() == IResource.ROOT
				|| resource.getType() == IResource.PROJECT)
			return false;
		return true;
	}

	public static boolean isDeleteAvailable(final IStructuredSelection selection)
			throws ModelException {
		if (!selection.isEmpty())
			return isDeleteAvailable(selection.toArray());
		return false;
	}

	public static boolean isDeleteAvailable(final Object[] objects)
			throws ModelException {
		if (objects.length != 0) {
			final IResource[] resources = RefactoringAvailabilityTester
					.getResources(objects);
			final IModelElement[] elements = RefactoringAvailabilityTester
					.getScriptElements(objects);
			if (objects.length != resources.length + elements.length)
				return false;
			for (int index = 0; index < resources.length; index++) {
				if (!isDeleteAvailable(resources[index]))
					return false;
			}
			for (int index = 0; index < elements.length; index++) {
				if (!isDeleteAvailable(elements[index]))
					return false;
			}
			return true;
		}
		return false;
	}

	public static boolean isWorkingCopyElement(final IModelElement element) {
		if (element instanceof ISourceModule)
			return ((ISourceModule) element).isWorkingCopy();
		if (ReorgUtils.isInsideSourceModule(element))
			return ReorgUtils.getSourceModule(element).isWorkingCopy();
		return false;
	}

	private RefactoringAvailabilityTester() {
		// Not for instantiation
	}

	public static boolean isMoveAvailable(final IResource[] resources,
			final IModelElement[] elements) throws ModelException {
		if (elements != null) {
			for (int index = 0; index < elements.length; index++) {
				IModelElement element = elements[index];
				if ((element instanceof IType)) {
					return false;
				}
				// if ((element instanceof IPackageDeclaration))
				// return false;
				if (element instanceof IField) {// && DLTKFlags.isEnum((IMember)
					// element))
					return false;
				}
			}
		}
		return ReorgPolicyFactory.createMovePolicy(resources, elements)
				.canEnable();
	}

	public static boolean isMoveAvailable(final ModelTextSelection selection)
			throws ModelException {
		final IModelElement element = selection.resolveEnclosingElement();
		if (element == null)
			return false;
		return isMoveAvailable(new IResource[0],
				new IModelElement[] { element });
	}
}
