package org.eclipse.jst.jsf.core.jsfappconfig.internal;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jst.jsf.common.internal.resource.ResourceSingletonObjectManager;
import org.eclipse.jst.jsf.common.internal.strategy.AbstractTestableExtensibleDefaultProviderSelectionStrategy;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;

/**
 * Responsible for producing and caching {@link IJSFAppConfigManager} instances by project.
 * <p>
 * This class will guarantee that he same instance of the {@link IJSFAppConfigManager} is returned for a given project
 *
 */
public class JSFAppConfigManagerFactory 
		extends 
			ResourceSingletonObjectManager<IJSFAppConfigManager, IProject>{
	
	private static JSFAppConfigManagerFactory INSTANCE;

	//private constructor
	private JSFAppConfigManagerFactory(final IProject project) {
		super(project.getWorkspace());
	}
	
	/**
	 * Project property session key for testing.
	 * Project value should hold the testable IJSFAppConfigManagerFactory instance or null
	 * NOT API - for testing purposes
	 */
	public static final QualifiedName TESTABLE_FACTORY_SESSION_KEY = new QualifiedName(JSFCorePlugin.PLUGIN_ID, "JSFAppConfigManagerFactoryInstance"); //$NON-NLS-1$
	
	/**
	 * @param project
	 * @return IJSFAppConfigManager
	 */
	public static IJSFAppConfigManager getJSFAppConfigManagerInstance(final IProject project) {
		try {
			return getJSFAppConfigManagerFactoryInstance(project).getInstance(project);			
		} catch (ManagedObjectException e) {
			JSFCorePlugin.log(e, "Cannot create IJSFAppConfigManager for "+project.getName()+ " (1)"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return null;
	}
	
	private synchronized static JSFAppConfigManagerFactory getJSFAppConfigManagerFactoryInstance(final IProject project) {
		if (INSTANCE == null) {
			INSTANCE = new JSFAppConfigManagerFactory(project);
		}
		return INSTANCE;
	}

	@Override
	protected IJSFAppConfigManager createNewInstance(final IProject project) {
		try {
			final IJSFAppConfigManagerFactory factory = getJSFAppConfigManagerFactoryProviderInstance(project);
			if (factory != null) {
				IJSFAppConfigManager jsfAppConfigMgr = factory.getInstance(project);

                // Make a call to ensure the underlying EMF models in
				// the providers (from the locators) are initialized
                // in this instance begin created. Helps avoid some
                // potential concurrency issues as models are created.
				jsfAppConfigMgr.getApplications();

				return jsfAppConfigMgr;
			}
		} catch (ManagedObjectException e) {
			JSFCorePlugin.log(e, "Cannot create IJSFAppConfigManager for "+project.getName()+ " (2)"); //$NON-NLS-1$ //$NON-NLS-2$
		}			
		return null;
	}

    @Override
    protected IAdaptable unsafeRunBeforeGetInstance(IProject project) {
        super.unsafeRunBeforeGetInstance(project);

        if (!isInstance(project) && Job.getJobManager().currentRule() == null) {
                //Acquire a scheduling rule on the project so creation of a JSFAppConfigManager
                //does not attempt to acquire a rule which may be unavailable while still
                //synchronized on the ResourceSingletonObjectManager (JSFAppConfigManagerFactory)
                Job.getJobManager().beginRule(project, null);
                return new AdaptableBoolean(true);
        }
        return null;
    }

    @Override
    protected void unsafeRunAfterGetInstance(IProject project, IAdaptable stateObject) {
        super.unsafeRunAfterGetInstance(project, stateObject);

        if (stateObject instanceof AdaptableBoolean && ((AdaptableBoolean)stateObject).acquiredRule) {
            Job.getJobManager().endRule(project);
        }
    }

    private IJSFAppConfigManagerFactory getJSFAppConfigManagerFactoryProviderInstance(final IProject project) {
		final CompositeFactorySelectionStrategyProvider factoryProvider = new CompositeFactorySelectionStrategyProvider();		
		return factoryProvider != null ? factoryProvider.getFactoryToUse(project) : null;
	}
	
	private static class CompositeFactorySelectionStrategyProvider
	{
		public IJSFAppConfigManagerFactory getFactoryToUse(final IProject project) {
			final JSFAppConfigManagerProviderSelectionStrategy providerSelector = new JSFAppConfigManagerProviderSelectionStrategy();		
	        addStrategies(providerSelector);
	        
			final IJSFAppConfigManagerFactory provider = providerSelector.perform(project);
	        if (provider != providerSelector.getNoResult())
	        {
	            return provider;
	        }
	        return null;
		}
		
		private void addStrategies(final JSFAppConfigManagerProviderSelectionStrategy providerSelector) {
			providerSelector.addDefaultStrategy(new DefaultJSFAppConfigManagerProviderStrategy());
			providerSelector.addExtensionStrategy(new ExtensionBasedJSFAppConfigManagerProviderStrategy());
			providerSelector.addTestableStrategy(new TestableJSFAppConfigManagerProviderStrategy(TESTABLE_FACTORY_SESSION_KEY));				
		}
		
	}
	
	private static class JSFAppConfigManagerProviderSelectionStrategy
		extends
			AbstractTestableExtensibleDefaultProviderSelectionStrategy<IProject, IJSFAppConfigManagerFactory> {
		
		private static final IJSFAppConfigManagerFactory NO_RESULT = null;
		
		@Override
		public IJSFAppConfigManagerFactory getNoResult() {
			return NO_RESULT;
		}
	}      private static class AdaptableBoolean implements IAdaptable {
        private final boolean acquiredRule;
        
        public AdaptableBoolean(boolean acquiredRule) {
            this.acquiredRule = acquiredRule;
        }

        public Object getAdapter(Class adapter) {
            return null;
        }   
    }
	
}
