/*******************************************************************************
 * 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 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.jst.j2ee.internal.plugin.J2EEPlugin;

/**
 * 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) {
			J2EEPlugin.log(J2EEPlugin.createErrorStatus(0, project.getName(), 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) {
			J2EEPlugin.log(J2EEPlugin.createErrorStatus(0, javaproject.getProject().getName(), 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) {
				J2EEPlugin.log(J2EEPlugin.createErrorStatus(0, "DependencyCache::getRequiredJavaProjects(" + javaproject.getProject().getName() + ") IJavaModel == null", null));  //$NON-NLS-1$//$NON-NLS-2$

				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) {
					J2EEPlugin.log(J2EEPlugin.createErrorStatus(0, javaproject.getProject().getName(), 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) {
			J2EEPlugin.log(J2EEPlugin.createErrorStatus(0, javaproject.getProject().getName(), exc));

			return EMPTY_JAVAPROJECTS;
		}
	}
}
