/*******************************************************************************
 * Copyright (c) 2001, 2005 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.jst.j2ee.internal.validation;

import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.util.logger.LogEntry;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;

/**
 * This singleton keeps an internal record of project dependencies. That is, every IProject can
 * depend on, and be depended on by, other IProjects. Ditto IJavaProject. This class is updated when
 * a project(s) classpath changes.
 */
public final class DependencyUtil {
	private static final IProject[] EMPTY_PROJECTS = new IProject[0];
	private static final IJavaProject[] EMPTY_JAVAPROJECTS = new IJavaProject[0];

	private static Set _tempSet = null;

	/**
	 * This is a set for temporary calculations.
	 */
	private static Set getTempSet() {
		if (_tempSet == null) {
			_tempSet = new HashSet();
		} else {
			_tempSet.clear();
		}
		return _tempSet;
	}

	/**
	 * Return an array of open IProjects which depend on the given IProject parameter.
	 */
	public static IProject[] getDependentProjects(IProject project) {
		if (project == null) {
			return EMPTY_PROJECTS;
		}

		IProject[] allProjects = project.getWorkspace().getRoot().getProjects();
		Set tempSet = getTempSet();
		for (int i = 0; i < allProjects.length; i++) {
			IProject p = allProjects[i];
			IProject[] requires = getRequiredProjects(p);
			for (int j = 0; j < requires.length; j++) {
				IProject r = requires[j];
				if (project.equals(r)) {
					tempSet.add(p);
					break;
				}
			}
		}
		IProject[] dependency = new IProject[tempSet.size()];
		tempSet.toArray(dependency);
		return dependency;
	}

	/**
	 * Return an array of open IProjects which the given IProject parameter depends on.
	 */
	public static IProject[] getRequiredProjects(IProject project) {
		if (project == null) {
			return EMPTY_PROJECTS;
		}

		// Check that each project in this list exists and is open
		try {
			IProject[] refProjects = project.getReferencedProjects();
			if ((refProjects == null) || (refProjects.length == 0)) {
				return EMPTY_PROJECTS;
			}

			IProject[] temp = new IProject[refProjects.length];
			int count = 0;
			for (int i = 0; i < refProjects.length; i++) {
				IProject rProject = refProjects[i];
				if (rProject.exists() && rProject.isOpen()) {
					temp[count++] = rProject;
				}
			}

			if (count == 0) {
				return EMPTY_PROJECTS;
			}

			if (count == temp.length) {
				return temp;
			}

			IProject[] result = new IProject[count];
			System.arraycopy(temp, 0, result, 0, count);
			return result;
		} catch (CoreException exc) {
			Logger logger = J2EEPlugin.getDefault().getMsgLogger();
			if (logger.isLoggingLevel(Level.SEVERE)) {
				LogEntry entry = J2EEPlugin.getDefault().getLogEntry();
				entry.setSourceID("DependencyCache::getRequiredProjects(" + project.getName() + ")"); //$NON-NLS-1$  //$NON-NLS-2$
				entry.setTargetException(exc);
				logger.write(Level.SEVERE, exc);
			}

			return EMPTY_PROJECTS;
		}
	}

	/**
	 * Return an array of open IJavaProjects which depend on the given IJavaProject parameter.
	 */
	public static IJavaProject[] getDependentJavaProjects(IJavaProject javaproject) {
		if (javaproject == null) {
			return EMPTY_JAVAPROJECTS;
		}

		// calculate the dependencies now.
		try {
			IJavaProject[] allProjects = javaproject.getJavaModel().getJavaProjects();
			Set tempSet = getTempSet();
			for (int i = 0; i < allProjects.length; i++) {
				IJavaProject p = allProjects[i];
				IJavaProject[] requires = getRequiredJavaProjects(p);
				for (int j = 0; j < requires.length; j++) {
					IJavaProject r = requires[j];
					if (javaproject.equals(r)) {
						tempSet.add(p);
						break;
					}
				}
			}
			IJavaProject[] dependency = new IJavaProject[tempSet.size()];
			tempSet.toArray(dependency);
			return dependency;
		} catch (JavaModelException exc) {
			Logger logger = J2EEPlugin.getDefault().getMsgLogger();
			if (logger.isLoggingLevel(Level.SEVERE)) {
				LogEntry entry = J2EEPlugin.getDefault().getLogEntry();
				entry.setSourceID("DependencyCache::getDependentJavaProjects(" + javaproject.getProject().getName() + ")"); //$NON-NLS-1$  //$NON-NLS-2$
				entry.setTargetException(exc);
				logger.write(Level.SEVERE, exc);
			}

			return EMPTY_JAVAPROJECTS;
		}
	}

	/**
	 * Return an array of open IJavaProjects which the given IJavaProject parameter depends on.
	 */
	public static IJavaProject[] getRequiredJavaProjects(IJavaProject javaproject) {
		if (javaproject == null) {
			return EMPTY_JAVAPROJECTS;
		}

		try {
			IJavaModel jm = javaproject.getJavaModel();
			if (jm == null) {
				Logger logger = J2EEPlugin.getDefault().getMsgLogger();
				if (logger.isLoggingLevel(Level.SEVERE)) {
					LogEntry entry = J2EEPlugin.getDefault().getLogEntry();
					entry.setSourceID("DependencyCache::getRequiredJavaProjects(" + javaproject.getProject().getName() + ")"); //$NON-NLS-1$  //$NON-NLS-2$
					//entry.setText("IJavaModel == null"); //$NON-NLS-1$
					logger.write(Level.SEVERE, "IJavaModel == null"); //$NON-NLS-1$
				}
				return EMPTY_JAVAPROJECTS;
			}

			String[] requiredProjects = javaproject.getRequiredProjectNames();
			if ((requiredProjects == null) || (requiredProjects.length == 0)) {
				return EMPTY_JAVAPROJECTS;
			}

			IJavaProject[] temp = new IJavaProject[requiredProjects.length];
			int count = 0;
			for (int i = 0; i < requiredProjects.length; i++) {
				String projectName = requiredProjects[i];
				IJavaProject jp = jm.getJavaProject(projectName);
				try {
					if ((jp == null) || (!jp.getProject().exists())) {
						continue;
					}
					if (!jp.getProject().isAccessible()) {
						continue;
					}

					if (!jp.getProject().hasNature(JavaCore.NATURE_ID)) {
						continue;
					}

					temp[count++] = jp;
				} catch (CoreException exc) {
					Logger logger = J2EEPlugin.getDefault().getMsgLogger();
					if (logger.isLoggingLevel(Level.SEVERE)) {
						LogEntry entry = J2EEPlugin.getDefault().getLogEntry();
						entry.setSourceID("DependencyCache::getRequiredJavaProjects(" + javaproject.getProject().getName() + ")"); //$NON-NLS-1$  //$NON-NLS-2$
						entry.setTargetException(exc);
						logger.write(Level.SEVERE, exc);
					}
					continue;
				}
			}

			if (count == 0) {
				return EMPTY_JAVAPROJECTS;
			}

			if (count == temp.length) {
				return temp;
			}

			IJavaProject[] result = new IJavaProject[count];
			System.arraycopy(temp, 0, result, 0, count);
			return result;
		} catch (JavaModelException exc) {
			Logger logger = J2EEPlugin.getDefault().getMsgLogger();
			if (logger.isLoggingLevel(Level.SEVERE)) {
				LogEntry entry = J2EEPlugin.getDefault().getLogEntry();
				entry.setSourceID("DependencyCache::getRequiredJavaProjects(" + javaproject.getProject().getName() + ")"); //$NON-NLS-1$  //$NON-NLS-2$
				entry.setTargetException(exc);
				logger.write(Level.SEVERE, exc);
			}

			return EMPTY_JAVAPROJECTS;
		}
	}
}
