/*******************************************************************************
 * Copyright (c) 2006, 2007 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.core.internal;

import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jpt.core.internal.IJpaProject.Config;
import org.eclipse.jpt.utility.internal.ClassTools;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.model.AbstractModel;

/**
 * The JPA model is synchronized so all changes to the list of JPA projects
 * are thread-safe.
 * 
 * The JPA model holds on to a list of JPA project configs and only instantiates
 * their associated JPA projects when necessary. Other than performance,
 * this should be transparent to clients.
 */
public class JpaModel extends AbstractModel implements IJpaModel {

	/** maintain a list of all the current JPA projects */
	private ArrayList<IJpaProjectHolder> jpaProjectHolders = new ArrayList<IJpaProjectHolder>();


	// ********** constructor **********

	/**
	 * Construct a JPA model and populate it with JPA projects to be built
	 * from the specified set of JPA project configs.
	 * The JPA model can only be instantiated by the JPA model manager.
	 */
	JpaModel(Iterable<IJpaProject.Config> configs) {
		super();
		for (IJpaProject.Config config : configs) {
			this.addJpaProject(config);
		}
	}


	// ********** IJpaModel implementation **********

	/**
	 * This will trigger the instantiation of the JPA project associated with the
	 * specified Eclipse project.
	 */
	public synchronized IJpaProject jpaProject(IProject project) throws CoreException {
		return this.jpaProjectHolder(project).jpaProject();
	}

	/**
	 * We can answer this question without instantiating the
	 * associated JPA project.
	 */
	public synchronized boolean containsJpaProject(IProject project) {
		return this.jpaProjectHolder(project).holdsJpaProjectFor(project);
	}

	/**
	 * This will trigger the instantiation of all the JPA projects.
	 */
	public synchronized Iterator<IJpaProject> jpaProjects() throws CoreException {
		// force the CoreException to occur here (instead of later, in Iterator#next())
		ArrayList<IJpaProject> jpaProjects = new ArrayList<IJpaProject>(this.jpaProjectHolders.size());
		for (IJpaProjectHolder holder : this.jpaProjectHolders) {
			jpaProjects.add(holder.jpaProject());
		}
		return jpaProjects.iterator();
	}

	/**
	 * We can answer this question without instantiating any JPA projects.
	 */
	public synchronized int jpaProjectsSize() {
		return this.jpaProjectHolders.size();
	}

	public synchronized IJpaFile jpaFile(IFile file) throws CoreException {
		IJpaProject jpaProject = this.jpaProject(file.getProject());
		return (jpaProject == null) ? null : jpaProject.jpaFile(file);
	}

	// ********** internal methods **********

	/**
	 * never return null
	 */
	private IJpaProjectHolder jpaProjectHolder(IProject project) {
		for (IJpaProjectHolder holder : this.jpaProjectHolders) {
			if (holder.holdsJpaProjectFor(project)) {
				return holder;
			}
		}
		return NullJpaProjectHolder.instance();
	}

	/**
	 * Add a JPA project to the JPA model for the specified Eclipse project.
	 * JPA projects can only be added by the JPA model manager.
	 * The JPA project will only be instantiated later, on demand.
	 */
	synchronized void addJpaProject(IJpaProject.Config config) {
		dumpStackTrace();  // figure out exactly when JPA projects are built
		this.jpaProjectHolders.add(this.jpaProjectHolder(config.project()).buildJpaProjectHolder(this, config));
	}

	/**
	 * Remove the JPA project corresponding to the specified Eclipse project
	 * from the JPA model. Return whether the removal actually happened.
	 * JPA projects can only be removed by the JPA model manager.
	 */
	synchronized boolean removeJpaProject(IProject project) {
		dumpStackTrace();  // figure out exactly when JPA projects are removed
		if (containsJpaProject(project)) {
			return this.jpaProjectHolder(project).remove();
		}
		return false;
	}

	/**
	 * Dispose the JPA model by disposing and removing all its JPA projects.
	 * The JPA model can only be disposed by the JPA model manager.
	 */
	synchronized void dispose() {
		// clone the list to prevent concurrent modification exceptions
		@SuppressWarnings("unchecked")
		ArrayList<IJpaProjectHolder> holders = (ArrayList<IJpaProjectHolder>) this.jpaProjectHolders.clone();
		for (IJpaProjectHolder holder : holders) {
			holder.remove();
		}
	}

	@Override
	public void toString(StringBuilder sb) {
		sb.append("JPA projects size: " + this.jpaProjectsSize());
	}


	// ********** events **********

	synchronized void synchronizeFiles(IProject project, IResourceDelta delta)  throws CoreException {
		if (containsJpaProject(project)) {
			this.synchronizeJpaFiles(project, delta);
		}
	}

	/**
	 * Forward the specified resource delta to the JPA project corresponding
	 * to the specified Eclipse project.
	 */
	private void synchronizeJpaFiles(IProject project, IResourceDelta delta) throws CoreException {
		this.jpaProjectHolder(project).synchronizeJpaFiles(delta);
	}

	/**
	 * Forward the Java element changed event to all the JPA projects
	 * because the event could affect multiple projects.
	 */
	synchronized void javaElementChanged(ElementChangedEvent event) {
		for (IJpaProjectHolder jpaProjectHolder : this.jpaProjectHolders) {
			jpaProjectHolder.javaElementChanged(event);
		}
	}


	// ********** holder callbacks **********

	/**
	 * called by the JPA project holder when the JPA project is actually
	 * instantiated
	 */
	/* private */ void jpaProjectBuilt(IJpaProject jpaProject) {
		this.fireItemAdded(JPA_PROJECTS_COLLECTION, jpaProject);
	}

	/**
	 * called by the JPA project holder if the JPA project has been
	 * instantiated and we need to remove it
	 */
	/* private */ void jpaProjectRemoved(IJpaProject jpaProject) {
		this.fireItemRemoved(JPA_PROJECTS_COLLECTION, jpaProject);
	}

	/**
	 * called by the JPA project holder
	 */
	/* private */ void removeJpaProjectHolder(IJpaProjectHolder jpaProjectHolder) {
		this.jpaProjectHolders.remove(jpaProjectHolder);
	}


	// ********** JPA project holder **********

	private interface IJpaProjectHolder {

		boolean holdsJpaProjectFor(IProject project);

		IJpaProject jpaProject() throws CoreException;

		void synchronizeJpaFiles(IResourceDelta delta) throws CoreException;

		void javaElementChanged(ElementChangedEvent event);

		IJpaProjectHolder buildJpaProjectHolder(JpaModel jpaModel, IJpaProject.Config config);

		boolean remove();

	}

	private static class NullJpaProjectHolder implements IJpaProjectHolder {
		private static final IJpaProjectHolder INSTANCE = new NullJpaProjectHolder();

		static IJpaProjectHolder instance() {
			return INSTANCE;
		}

		// ensure single instance
		private NullJpaProjectHolder() {
			super();
		}

		public boolean holdsJpaProjectFor(IProject project) {
			return false;
		}

		public IJpaProject jpaProject() throws CoreException {
			return null;
		}

		public void synchronizeJpaFiles(IResourceDelta delta) throws CoreException {
			// do nothing
		}

		public void javaElementChanged(ElementChangedEvent event) {
			// do nothing
		}

		public IJpaProjectHolder buildJpaProjectHolder(JpaModel jpaModel, Config config) {
			return new JpaProjectHolder(jpaModel, config);
		}

		public boolean remove() {
			return false;
		}

		@Override
		public String toString() {
			return ClassTools.shortClassNameForObject(this);
		}
	}

	/**
	 * Pair a JPA project config with its lazily-initialized JPA project.
	 */
	private static class JpaProjectHolder implements IJpaProjectHolder {
		private final JpaModel jpaModel;
		private final IJpaProject.Config config;
		private IJpaProject jpaProject;

		JpaProjectHolder(JpaModel jpaModel, IJpaProject.Config config) {
			super();
			this.jpaModel = jpaModel;
			this.config = config;
		}

		public boolean holdsJpaProjectFor(IProject project) {
			return this.config.project().equals(project);
		}

		public IJpaProject jpaProject() throws CoreException {
			if (this.jpaProject == null) {
				this.jpaProject = this.buildJpaProject();
				// notify listeners of the JPA model
				this.jpaModel.jpaProjectBuilt(this.jpaProject);
			}
			return this.jpaProject;
		}

		private IJpaProject buildJpaProject() throws CoreException {
			return this.config.jpaPlatform().getJpaFactory().createJpaProject(this.config);
		}

		public void synchronizeJpaFiles(IResourceDelta delta) throws CoreException {
			if (this.jpaProject != null) {
				this.jpaProject.synchronizeJpaFiles(delta);
			}
		}

		public void javaElementChanged(ElementChangedEvent event) {
			if (this.jpaProject != null) {
				this.jpaProject.javaElementChanged(event);
			}
		}

		public IJpaProjectHolder buildJpaProjectHolder(JpaModel jm, Config c) {
			throw new IllegalArgumentException(c.project().getName());
		}

		public boolean remove() {
			this.jpaModel.removeJpaProjectHolder(this);
			if (this.jpaProject != null) {
				this.jpaModel.jpaProjectRemoved(this.jpaProject);
				this.jpaProject.dispose();
			}
			return true;
		}

		@Override
		public String toString() {
			return StringTools.buildToStringFor(this, this.config.project().getName());
		}

	}


	// ********** debug **********

	private static final boolean DEBUG = false;

	private static void dumpStackTrace() {
		if (DEBUG) {
			// lock System.out so the stack elements are printed out contiguously
			synchronized (System.out) {
				StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
				// skip the first 3 elements - those are this method and 2 methods in Thread
				for (int i = 3; i < stackTrace.length; i++) {
					StackTraceElement element = stackTrace[i];
					if (element.getMethodName().equals("invoke0")) {
						break;  // skip all elements outside of the JUnit test
					}
					System.out.println("\t" + element);
				}
			}
		}
	}

}
