/*******************************************************************************
 * Copyright (c) 2006, 2008 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;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jpt.core.internal.JpaModelManager;
import org.eclipse.jpt.core.internal.platform.GenericJpaPlatform;
import org.eclipse.jpt.core.internal.platform.JpaPlatformRegistry;
import org.eclipse.jpt.core.internal.prefs.JpaPreferenceConstants;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;
import org.osgi.framework.BundleContext;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;

/**
 * The JPT plug-in lifecycle implementation.
 * A number of globally-available constants and methods.
 * 
 * Provisional API: This class is part of an interim API that is still
 * under development and expected to change significantly before reaching
 * stability. It is available at this early stage to solicit feedback from
 * pioneering adopters on the understanding that any code that uses this API
 * will almost certainly be broken (repeatedly) as the API evolves.
 */
// TODO keep preferences in synch with the JPA project
// (connection profile name, "discover" flag)
// use listeners?
public class JptCorePlugin extends Plugin {


	// ********** public constants **********

	/**
	 * The plug-in identifier of the persistence support
	 * (value <code>"org.eclipse.jpt.core"</code>).
	 */
	public static final String PLUGIN_ID = "org.eclipse.jpt.core";  //$NON-NLS-1$

	/**
	 * The identifier for the JPA facet
	 * (value <code>"jpt.jpa"</code>).
	 */
	public static final String FACET_ID = "jpt.jpa";  //$NON-NLS-1$

	/**
	 * The key for storing a JPA project's platform in the Eclipse
	 * project's preferences.
	 */
	public static final String JPA_PLATFORM = PLUGIN_ID + ".platform";  //$NON-NLS-1$
	
	/**
	 * The key for storing a JPA project's "discover" flag in the Eclipse
	 * project's preferences.
	 */
	public static final String DISCOVER_ANNOTATED_CLASSES = PLUGIN_ID + ".discoverAnnotatedClasses";  //$NON-NLS-1$

	/**
	 * The key for storing a JPA project's data source connection profile name
	 * in the Eclipse project's persistent properties.
	 */
	public static final QualifiedName DATA_SOURCE_CONNECTION_PROFILE_NAME = 
			new QualifiedName(PLUGIN_ID, "dataSource.connectionProfileName");  //$NON-NLS-1$

	/**
	 * The key for storing a JPA project's user overridden default schema name
	 * in the Eclipse project's persistent properties.
	 */
	public static final QualifiedName USER_OVERRIDE_DEFAULT_SCHEMA_NAME = 
			new QualifiedName(PLUGIN_ID, "userOverrideDefaultSchemaName");  //$NON-NLS-1$
	
	/**
	 * The identifier for the JPA validation marker
	 * (value <code>"org.eclipse.jpt.core.jpaProblemMarker"</code>).
	 */
	public static final String VALIDATOR_ID = PLUGIN_ID + ".jpaValidator";  //$NON-NLS-1$

	/**
	 * Value of the content-type for orm.xml mappings files. Use this value to retrieve 
	 * the ORM xml content type from the content type manager and to add new 
	 * orm.xml-like extensions to this content type.
	 * 
	 * @see org.eclipse.core.runtime.content.IContentTypeManager#getContentType(String)
	 */
	public static final String ORM_XML_CONTENT_TYPE = PLUGIN_ID + ".content.orm"; //$NON-NLS-1$

	/**
	 * Ditto for persistence.xml.
	 * @see #ORM_XML_CONTENT_TYPE
	 */
	public static final String PERSISTENCE_XML_CONTENT_TYPE = PLUGIN_ID + ".content.persistence"; //$NON-NLS-1$

	/**
	 * Web projects have some special exceptions.
	 */
	public static final String WEB_PROJECT_FACET_ID = IModuleConstants.JST_WEB_MODULE;

	/**
	 * Web projects have some special exceptions.
	 */
	public static final String WEB_PROJECT_DEPLOY_PREFIX = J2EEConstants.WEB_INF_CLASSES;

	public static final String DEFAULT_PERSISTENCE_XML_FILE_PATH = "META-INF/persistence.xml"; //$NON-NLS-1$

	public static final String DEFAULT_ORM_XML_FILE_PATH = "META-INF/orm.xml"; //$NON-NLS-1$


	// ********** singleton **********

	private static JptCorePlugin INSTANCE;

	/**
	 * Return the singleton JPT plug-in.
	 */
	public static JptCorePlugin instance() {
		return INSTANCE;
	}


	// ********** public static methods **********

	/**
	 * Return the singular JPA model corresponding to the current workspace.
	 */
	public static JpaModel getJpaModel() {
		return JpaModelManager.instance().getJpaModel();
	}

	/**
	 * Return the JPA project corresponding to the specified Eclipse project,
	 * or null if unable to associate the specified project with a
	 * JPA project.
	 */
	public static JpaProject getJpaProject(IProject project) {
		try {
			return JpaModelManager.instance().getJpaProject(project);
		} catch (CoreException ex) {
			log(ex);
			return null;
		}
	}

	/**
	 * Return the JPA file corresponding to the specified Eclipse file,
	 * or null if unable to associate the specified file with a JPA file.
	 */
	public static JpaFile getJpaFile(IFile file) {
		try {
			return JpaModelManager.instance().getJpaFile(file);
		} catch (CoreException ex) {
			log(ex);
			return null;
		}
	}

	/**
	 * Return whether the specified Eclipse project has a JPA facet.
	 */
	public static boolean projectHasJpaFacet(IProject project) {
		return projectHasFacet(project, FACET_ID);
	}

	/**
	 * Return whether the specified Eclipse project has a JPA facet.
	 */
	public static boolean projectHasWebFacet(IProject project) {
		return projectHasFacet(project, WEB_PROJECT_FACET_ID);
	}

	/**
	 * Checked exceptions bite.
	 */
	private static boolean projectHasFacet(IProject project, String facetId) {
		try {
			return FacetedProjectFramework.hasProjectFacet(project, facetId);
		} catch (CoreException ex) {
			log(ex);  // problems reading the project metadata - assume facet doesn't exist - return 'false'
			return false;
		}
	}

	/**
	 * Return the persistence.xml (specified as "META-INF/persistence.xml")
	 * deployment URI for the specified project.
	 */
	public static String getPersistenceXmlDeploymentURI(IProject project) {
		return getDeploymentURI(project, DEFAULT_PERSISTENCE_XML_FILE_PATH);
	}

	/**
	 * Return the default mapping file (specified as "META-INF/orm.xml")
	 * deployment URI for the specified project.
	 */
	public static String getDefaultOrmXmlDeploymentURI(IProject project) {
		return getDeploymentURI(project, DEFAULT_ORM_XML_FILE_PATH);
	}
	
	/**
	 * Return the mapping file (specified as "META-INF/<mappingFileName>")
	 * deployment URI for the specified project.
	 */
	public static String getOrmXmlDeploymentURI(IProject project, String mappingFileName) {
		return getDeploymentURI(project, mappingFileName);
	}
	
	/**
	 * Tweak the specified deployment URI if the specified project
	 * has a web facet.
	 */
	public static String getDeploymentURI(IProject project, String defaultURI) {
		return projectHasWebFacet(project) ?
				WEB_PROJECT_DEPLOY_PREFIX + '/' + defaultURI
			:
				defaultURI;
	}
	
	/**
	 * Return the default JPA preferences
	 * @see JpaPreferenceInitializer
	 */
	public static IEclipsePreferences getDefaultPreferences() {
		IScopeContext context = new DefaultScope();
		return context.getNode(PLUGIN_ID);
	}
	
	/**
	 * Return the JPA preferences for the current workspace instance.
	 */
	public static IEclipsePreferences getWorkspacePreferences() {
		IScopeContext context = new InstanceScope();
		return context.getNode(PLUGIN_ID);
	}
	
	/**
	 * Return the JPA preferences for the specified Eclipse project.
	 */
	public static IEclipsePreferences getProjectPreferences(IProject project) {
		IScopeContext context = new ProjectScope(project);
		return context.getNode(PLUGIN_ID);
	}
	
	/**
	 * Return the default JPA library for creating new JPA projects
	 */
	public static String getDefaultJpaLibrary() {
		return Platform.getPreferencesService().get(
				JpaPreferenceConstants.PREF_DEFAULT_JPA_LIB, null,
				new Preferences[] {getWorkspacePreferences(), getDefaultPreferences()});
	}
	
	/**
	 * Return the default JPA platform ID for creating new JPA projects
	 */
	public static String getDefaultJpaPlatformId() {
		String platformId = 
			Platform.getPreferencesService().get(
				JpaPreferenceConstants.PREF_DEFAULT_JPA_PLATFORM, GenericJpaPlatform.ID,
				new Preferences[] {getWorkspacePreferences(), getDefaultPreferences()});
		if (! JpaPlatformRegistry.instance().containsPlatform(platformId)) {
			platformId = 
				Platform.getPreferencesService().get(
					JpaPreferenceConstants.PREF_DEFAULT_JPA_PLATFORM, GenericJpaPlatform.ID,
					new Preferences[] {getDefaultPreferences()});
		}
		return platformId;
	}
	
	/**
	 * Set the default JPA platform ID for creating new JPA projects
	 */
	public static void setDefaultJpaPlatformId(String platformId) {
		IEclipsePreferences prefs = getWorkspacePreferences();
		prefs.put(JpaPreferenceConstants.PREF_DEFAULT_JPA_PLATFORM, platformId);
		flush(prefs);
	}

	/**
	 * Return the JPA platform associated with the specified Eclipse project.
	 */
	public static JpaPlatform getJpaPlatform(IProject project) {
		return JpaPlatformRegistry.instance().getJpaPlatform(project);
	}
	
	/**
	 * Return the JPA platform ID associated with the specified Eclipse project.
	 */
	public static String getJpaPlatformId(IProject project) {
		return getProjectPreferences(project).get(JPA_PLATFORM, GenericJpaPlatform.ID);
	}

	/**
	 * Set the JPA platform ID associated with the specified Eclipse project.
	 */
	public static void setJpaPlatformId(IProject project, String jpaPlatformId) {
		IEclipsePreferences prefs = getProjectPreferences(project);
		prefs.put(JPA_PLATFORM, jpaPlatformId);
		flush(prefs);
	}
	
	/**
	 * Return the JPA "discover" flag associated with the specified
	 * Eclipse project.
	 */
	public static boolean discoverAnnotatedClasses(IProject project) {
		return getProjectPreferences(project).getBoolean(DISCOVER_ANNOTATED_CLASSES, false);
	}

	/**
	 * Set the JPA "discover" flag associated with the specified
	 * Eclipse project.
	 */
	public static void setDiscoverAnnotatedClasses(IProject project, boolean discoverAnnotatedClasses) {
		IEclipsePreferences prefs = getProjectPreferences(project);
		prefs.putBoolean(DISCOVER_ANNOTATED_CLASSES, discoverAnnotatedClasses);
		flush(prefs);
	}

	/**
	 * checked exceptions bite
	 */
	private static void flush(IEclipsePreferences prefs) {
		try {
			prefs.flush();
		} catch(BackingStoreException ex) {
			log(ex);
		}
	}

	/**
	 * Return the name of the connection profile associated with the specified
	 * Eclipse project.
	 */
	public static String getConnectionProfileName(IProject project) {
		try {
			return project.getPersistentProperty(DATA_SOURCE_CONNECTION_PROFILE_NAME);
		} catch (CoreException ex) {
			log(ex);
			return null;
		}
	}

	/**
	 * Set the name of the connection profile associated with the specified
	 * Eclipse project.
	 */
	public static void setConnectionProfileName(IProject project, String connectionProfileName) {
		try {
			project.setPersistentProperty(DATA_SOURCE_CONNECTION_PROFILE_NAME, connectionProfileName);
		} catch (CoreException ex) {
			log(ex);
		}
	}
	
	/**
	 * Return the default schema name associated with the specified Eclipse project.
	 * @see JpaProject#getUserOverrideDefaultSchemaName()
	 */
	public static String getUserOverrideDefaultSchemaName(IProject project) {
		try {
			return project.getPersistentProperty(USER_OVERRIDE_DEFAULT_SCHEMA_NAME);
		}
		catch (CoreException ce) {
			log(ce);
			return null;
		}
	}
	
	/**
	 * Set the default schema name associated with the specified Eclipse project.
	 * @see JpaProject#setUserOverrideDefaultSchemaName()
	 */
	public static void setUserOverrideDefaultSchemaName(IProject project, String defaultSchemaName) {
		try {
			project.setPersistentProperty(USER_OVERRIDE_DEFAULT_SCHEMA_NAME, defaultSchemaName);
		}
		catch (CoreException ce) {
			log(ce);
		}
	}

	/**
	 * Log the specified status.
	 */
	public static void log(IStatus status) {
        INSTANCE.getLog().log(status);
    }

	/**
	 * Log the specified message.
	 */
	public static void log(String msg) {
        log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, msg, null));
    }

	/**
	 * Log the specified exception or error.
	 */
	public static void log(Throwable throwable) {
		log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, throwable.getLocalizedMessage(), throwable));
	}


	// ********** plug-in implementation **********

	public JptCorePlugin() {
		super();
		if (INSTANCE != null) {
			throw new IllegalStateException();
		}
		// this convention is *wack*...  ~bjv
		INSTANCE = this;
	}


	@Override
	public void start(BundleContext context) throws Exception {
		super.start(context);
		JpaModelManager.instance().start();
	}

	@Override
	public void stop(BundleContext context) throws Exception {
		try {
			JpaModelManager.instance().stop();
		} finally {
			super.stop(context);
		}
	}

}
