/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation.
 * 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:
 *    Cameron Bateman/Oracle - initial API and implementation
 *    
 ********************************************************************************/

package org.eclipse.jst.jsf.designtime;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Properties;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.jsfappconfig.JSFAppConfigUtils;
import org.eclipse.jst.jsf.designtime.context.AbstractDTExternalContextFactory;
import org.eclipse.jst.jsf.designtime.context.DTFacesContext;
import org.eclipse.jst.jsf.designtime.context.IExternalContextFactoryLocator;
import org.eclipse.jst.jsf.designtime.el.AbstractDTMethodResolver;
import org.eclipse.jst.jsf.designtime.el.AbstractDTPropertyResolver;
import org.eclipse.jst.jsf.designtime.el.AbstractDTVariableResolver;
import org.eclipse.jst.jsf.designtime.internal.BasicExtensionFactory.ExtensionData;
import org.eclipse.jst.jsf.designtime.internal.view.IDTViewHandler;


/**
 * Per-web-application manager that manages design time information for a corresponding
 * project.
 * 
 * TODO: migrate to managed singleton
 * @author cbateman
 *
 */
public final class DesignTimeApplicationManager 
{
    // TODO: load from property file?
    private static final String   PROPERTY_QUALIFIER = "org.eclipse.jst.jsf.designtime.internal"; //$NON-NLS-1$
    private static final String   SESSION_PROPERTY_NAME_PROJECT = "DesignTimeApplicationManager"; //$NON-NLS-1$
    private static final QualifiedName  SESSION_PROPERTY_KEY_PROJECT 
        = new QualifiedName(PROPERTY_QUALIFIER, SESSION_PROPERTY_NAME_PROJECT);
    
    private static final String   SESSION_PROPERTY_NAME_FACES_CONTEXT = "DTFacesContext"; //$NON-NLS-1$
    private static final QualifiedName SESSION_PROPERTY_KEY_FACES_CONTEXT
       =  new QualifiedName(PROPERTY_QUALIFIER, SESSION_PROPERTY_NAME_FACES_CONTEXT);
    
    private static final String   PERSIST_PROPERTY_NAME_EXTERNAL_CONTEXT_PROVIDER =
        "ExternalContextProvider"; //$NON-NLS-1$
    private static final QualifiedName PERSIST_PROPERTY_KEY_EXTERNAL_CONTEXT_PROVIDER =
        new QualifiedName(PROPERTY_QUALIFIER, PERSIST_PROPERTY_NAME_EXTERNAL_CONTEXT_PROVIDER);
    
    private static final String   PERSIST_PROPERTY_NAME_VARIABLE_RESOLVER_PROVIDER =
        "VariableResolverProvider"; //$NON-NLS-1$
    private static final QualifiedName PERSIST_PROPERTY_KEY_VARIABLE_RESOLVER_PROVIDER 
       = new QualifiedName(PROPERTY_QUALIFIER, PERSIST_PROPERTY_NAME_VARIABLE_RESOLVER_PROVIDER);

    private static final String   PERSIST_PROPERTY_NAME_PROPERTY_RESOLVER_PROVIDER =
        "PropertyResolverProvider"; //$NON-NLS-1$
    private static final QualifiedName PERSIST_PROPERTY_KEY_PROPERTY_RESOLVER_PROVIDER =
        new QualifiedName(PROPERTY_QUALIFIER, PERSIST_PROPERTY_NAME_PROPERTY_RESOLVER_PROVIDER);

    private static final String    PERSIST_PROPERTY_NAME_METHOD_RESOLVER_PROVIDER =
        "MethodResolverProvider"; //$NON-NLS-1$
    private static final QualifiedName PERSIST_PROPERTY_KEY_METHOD_RESOLVER_PROVIDER =
        new QualifiedName(PROPERTY_QUALIFIER, PERSIST_PROPERTY_NAME_METHOD_RESOLVER_PROVIDER);

    private static final String    PERSIST_PROPERTY_NAME_VIEW_HANDLER =
        "ViewHandler";  //$NON-NLS-1$
    
    private static final String   DEFAULT_EXTERNAL_CONTEXT_ID = 
        "org.eclipse.jst.jsf.core.externalcontext.default"; //$NON-NLS-1$
    
    private static final String   DEFAULT_VARIABLE_RESOLVER_ID = 
        "org.eclipse.jst.jsf.core.variableresolver.default.decorative"; //$NON-NLS-1$
    
    private static final String   DEFAULT_PROPERTY_RESOLVER_ID =
        "org.eclipse.jst.jsf.core.propertyresolver.default.decorative"; //$NON-NLS-1$
        
    private static final String   DEFAULT_METHOD_RESOLVER_ID =
        "org.eclipse.jst.jsf.core.methodresolver.default"; //$NON-NLS-1$

    private static final String   DEFAULT_VIEW_HANDLER_ID =
        "org.eclipse.jst.jsf.designtime.view.jspviewhandler"; //$NON-NLS-1$
    
    /**
     * @param project
     * @return the app manager associated with project
     */
    public final static DesignTimeApplicationManager getInstance(IProject project)
    {
        if (!hasJSFDesignTime(project))
        {
            return null;
        }
        
        try
        {
            synchronized(project)
            {
                DesignTimeApplicationManager manager = 
                    (DesignTimeApplicationManager) project.getSessionProperty(SESSION_PROPERTY_KEY_PROJECT);

                
                if (manager == null)
                {
                    manager = new DesignTimeApplicationManager(project);
                    project.setSessionProperty(SESSION_PROPERTY_KEY_PROJECT, manager);
                }
                // bug 147729: if project was renamed, the project param will be
                // valid, but it will not be in sync with the one for _project
                // unfortunately, since we are using session propertie
                else
                {
                    synchronized(manager)
                    {
                        if (!project.equals(manager._project))
                        {
                            manager._project = project;
                        }
                    }
                }

                return manager;
            }
        }
        catch (CoreException ce)
        {
            Platform.getLog(JSFCorePlugin.getDefault().getBundle()).log(new Status(IStatus.ERROR, JSFCorePlugin.getDefault().getBundle().getSymbolicName(), 0, "Problem loading design time appmanager", new Throwable(ce))); //$NON-NLS-1$
        }
        
        return null;
    }
    
    /**
     * The criteria for a project having a JSF design time are:
     * 
     * - project is non-null.
     * - project is accessible (project.isAccessible() == true)
     * - project has a JSF facet (this implies that it's dependent facets are also present).
     * 
     * @param project
     * @return true if project can have a JSF DesignTimeApplicationManager
     * associated with it.  getInstance(project) uses this determine if should
     * construct an instance for a project.
     */
    public static boolean hasJSFDesignTime(final IProject project)
    {
        return project != null && project.isAccessible() &&
            JSFAppConfigUtils.isValidJSFProject(project);
    }
    
    // instance definition
    // _project must be writable in case the manager needs to be retargetted
    // after a rename/move etc.
    private IProject                                    _project;
    private final IExternalContextFactoryLocator        _locator;
    //private IDTViewHandler                              _viewHandler;
    private Properties                                  _properties;
    
    private DesignTimeApplicationManager(IProject project)
    {
        _project = project;
        _locator = new MyExternalContextFactoryLocator();
        _properties = loadProperties(_project);
    }
    
    /**
     * @param file must not be null
     * @return the faces context for the file or null if not found
     */
    public DTFacesContext getFacesContext(IFile file)
    {
        if (!hasDTFacesContext(file))
        {
            return null;
        }
        
        try
        {
            synchronized(file)
            {
                Object context = file.getSessionProperty(SESSION_PROPERTY_KEY_FACES_CONTEXT);
                
                if (context == null)
                {
                    context = new DTFacesContext(file, _locator);
                    file.setSessionProperty(SESSION_PROPERTY_KEY_PROJECT, context);
                }
                
                return (DTFacesContext) context;
            }
        }
        catch (CoreException ce)
        {
            Platform.getLog(JSFCorePlugin.getDefault().getBundle())
                .log(new Status(IStatus.ERROR, 
                        JSFCorePlugin.getDefault().getBundle().getSymbolicName(), 
                        0, "Problem loading design time facescontext",  //$NON-NLS-1$
                        new Throwable(ce)));
        }
        
        return null;
    }
    
    /**
     * Only files for which a runtime request context will be generated
     * have a corresponding design time context.  This is generally confined
     * to view definition files such as JSP's.
     * 
     * General criteria for a file to have a design time faces context are:
     * 
     * - the file is non-null and isAccessible()
     * - the file has designtime view handler (getViewHandler(file) != null)
     * and it supports the content type of file.
     *
     * getFacesContext uses this to decide whether to generate a context
     * for an IFile.
     * 
     * @param file
     * @return true if file has a design time faces context
     */
    public boolean hasDTFacesContext(final IFile file)
    {
        IDTViewHandler viewHandler = getViewHandler();
        
        if (file != null && file.isAccessible()&&
                viewHandler != null && viewHandler.supportsViewDefinition(file))
        {
            return true;
        }
        return false;
    }
    /**
     * @return the design time view handler for this webap (project).
     */
    public synchronized IDTViewHandler getViewHandler()
    {
        final String viewHandlerId = 
            getFromProjectSettings(PERSIST_PROPERTY_NAME_VIEW_HANDLER
                                 , DEFAULT_VIEW_HANDLER_ID);
        
        if (viewHandlerId != null)
        {
            return JSFCorePlugin.getViewHandlers(viewHandlerId).getInstance(_project);
        }

        return null;
    }
    
    /**
     * Sets the persistent id on this project that will be used to load the
     * view handler.
     * 
     * @param viewHandlerId
     */
    public synchronized void setViewHandlerId(final String viewHandlerId)
    {
        setProjectSetting(PERSIST_PROPERTY_NAME_VIEW_HANDLER, viewHandlerId);
    }

    /**
     * @param resolverPluginId
     * @throws CoreException
     */
    public synchronized void setExternalContextProvider(final String resolverPluginId)
                                throws CoreException
    {
        _project.setPersistentProperty
            (PERSIST_PROPERTY_KEY_EXTERNAL_CONTEXT_PROVIDER, resolverPluginId);
    }
    
    /**
     * @return the id of the active design time external context provider
     */
    public synchronized String getExternalContextProvider()
    {
        return getResolverId(PERSIST_PROPERTY_KEY_EXTERNAL_CONTEXT_PROVIDER,
                DEFAULT_EXTERNAL_CONTEXT_ID);
    }
    
    /**
     * @return the designtime variable resolver for this application
     */
    public synchronized AbstractDTVariableResolver getVariableResolver()
    {
        ExtensionData<AbstractDTVariableResolver> extData = null;

        String id = getResolverId_OLD(PERSIST_PROPERTY_KEY_VARIABLE_RESOLVER_PROVIDER);
        if (id != null)
        {
            extData = JSFCorePlugin.getVariableResolvers(id);
        }
        
        if (extData == null)
        {
            extData = JSFCorePlugin.getVariableResolvers(DEFAULT_VARIABLE_RESOLVER_ID);
        }

        return extData.getInstance(_project);
    }

    /**
     * Sets the plugin used to determine the designtime variable resolver.  To 
     * reset to the default, pass null.
     * 
     * @param resolverPluginId
     * @throws CoreException -- if the setting the new value fails
     */
    public synchronized void setVariableResolverProvider(final String resolverPluginId)
                                throws CoreException
    {
        _project.setPersistentProperty
            (PERSIST_PROPERTY_KEY_VARIABLE_RESOLVER_PROVIDER, resolverPluginId);
    }
    
    /**
     * @return the id of the active design time variable resolver
     */
    public synchronized String getVariableResolverProvider()
    {
        return getResolverId(PERSIST_PROPERTY_KEY_VARIABLE_RESOLVER_PROVIDER,
                             DEFAULT_VARIABLE_RESOLVER_ID);
    }
    
    /**
     * @return the default property resolver that will be used if no other
     * is provided.  The default property resolver is intended to match the
     * similar resolver used by the runtime.
     */
    public synchronized AbstractDTPropertyResolver getDefaultPropertyResolver()
    {
        return JSFCorePlugin.getPropertyResolver(DEFAULT_PROPERTY_RESOLVER_ID).getInstance(_project);
    }
    
    /**
     * @return the designtime property resolver for this application 
     */
    public synchronized AbstractDTPropertyResolver getPropertyResolver()
    {
        ExtensionData<AbstractDTPropertyResolver> extData = null;

        String id = getResolverId_OLD(PERSIST_PROPERTY_KEY_PROPERTY_RESOLVER_PROVIDER);
        if (id != null)
        {
            extData = JSFCorePlugin.getPropertyResolver(id);
        }
        
        if (extData == null)
        {
            extData = JSFCorePlugin.getPropertyResolver(DEFAULT_PROPERTY_RESOLVER_ID);
        }

        return extData.getInstance(_project);
    }
    
    /**
     * @param resolverPluginId
     * @throws CoreException -- if setting the provider fails
     */
    public synchronized void setPropertyResolverProvider(final String resolverPluginId)
                                                  throws CoreException
    {
        _project.setPersistentProperty
            (PERSIST_PROPERTY_KEY_PROPERTY_RESOLVER_PROVIDER, resolverPluginId);       
    }

    /**
     * @return the id of the active design time variable resolver
     */
    public synchronized String getPropertyResolverProvider()
    {
        return getResolverId(PERSIST_PROPERTY_KEY_PROPERTY_RESOLVER_PROVIDER,
                             DEFAULT_PROPERTY_RESOLVER_ID);
    }

    /**
     * @return the designtime method resolver for this application
     */
    public synchronized AbstractDTMethodResolver getMethodResolver()
    {
        ExtensionData<AbstractDTMethodResolver> extData = null;

        String id = getResolverId_OLD(PERSIST_PROPERTY_KEY_METHOD_RESOLVER_PROVIDER);
        if (id != null)
        {
            extData = JSFCorePlugin.getMethodResolvers(id);
        }
        
        if (extData == null)
        {
            extData = JSFCorePlugin.getMethodResolvers(DEFAULT_METHOD_RESOLVER_ID);
        }

        return extData.getInstance(_project);
    }

    /**
     * @param resolverPluginId
     * @throws CoreException -- if setting the plugin fails
     */
    public synchronized void setMethodResolverProvider(final String resolverPluginId)
                                            throws CoreException
    {
        _project.setPersistentProperty
            (PERSIST_PROPERTY_KEY_METHOD_RESOLVER_PROVIDER, resolverPluginId);       

    }
    
    /**
     * @return the id of the active design time variable resolver
     */
    public synchronized String getMethodResolverProvider()
    {
        return getResolverId(PERSIST_PROPERTY_KEY_METHOD_RESOLVER_PROVIDER,
                             DEFAULT_METHOD_RESOLVER_ID);
    }

    private String getResolverId_OLD(final QualifiedName pluginKey)
    {
        String pluginId = null;
        
        try
        {
           pluginId =
                _project.getPersistentProperty(pluginKey);
        }
        catch (CoreException ce)
        {
            JSFCorePlugin.getDefault().getLog().log(
                    new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID,
                                0, "Error getting plugin property", //$NON-NLS-1$
                                ce));
            pluginId = null;
            // fall-through and use the default
        }

        return pluginId;
    }

    private String getResolverId(final QualifiedName key, final String defaultValue)
    {
        String id = defaultValue; 

        try
        {
            final String userId = 
                _project.getPersistentProperty(key);
            
            if (userId != null)
            {
                id = userId;
            }
        }
        catch (CoreException ce)
        {
            // do nothing; fall through and return default
        }

        return id;
    }
    
    private class MyExternalContextFactoryLocator implements IExternalContextFactoryLocator
    {
        public AbstractDTExternalContextFactory getFactory() 
        {
            ExtensionData<AbstractDTExternalContextFactory> extData = null;

            String id = getResolverId_OLD(PERSIST_PROPERTY_KEY_EXTERNAL_CONTEXT_PROVIDER);
            if (id != null)
            {
                extData = JSFCorePlugin.getExternalContextProviders(id);
            }
            
            if (extData == null)
            {
                extData = JSFCorePlugin.getExternalContextProviders(DEFAULT_EXTERNAL_CONTEXT_ID);
            }

            return extData.getInstance(_project);
        }
    }
    
    private String getFromProjectSettings(final String key, final String defaultValue)
    {
        return _properties.getProperty(key, defaultValue);
    }
    
    private void setProjectSetting(final String key, final String value)
    {
        _properties.setProperty(key, value);
        storeProperties(_properties);
    }
    
    private void storeProperties(final Properties properties)
    {
        IFile propFile;
        try
        {
            propFile = getPropsFile(_project);
            if (propFile != null)
            {
                final ByteArrayOutputStream  outstream =
                    new ByteArrayOutputStream();
                properties.store(outstream, null);
                propFile.setContents(new ByteArrayInputStream(outstream.toByteArray())
                    , true, true, null);
            }
        }
        catch (CoreException e)
        {
            JSFCorePlugin.log(e, "Problem storing properties");
        }
        catch (IOException e)
        {
            JSFCorePlugin.log(e, "Problem storing properties");
        }
    }
    
    private Properties loadProperties(final IProject project)
    {
        Properties props = new Properties();
        try
        {
            final IFile propFile = getPropsFile(project);
            
            if (propFile != null)
            {
                props.load(propFile.getContents());
            }
        }
        catch (CoreException ce)
        {
            JSFCorePlugin.log(ce, "Problem loading properties");
        }
        catch (IOException ce)
        {
            JSFCorePlugin.log(ce, "Problem loading properties");
        }
        
        return props;
    }
    
    private IFile getPropsFile(final IProject project) throws CoreException
    {
        IFolder  folder = project.getFolder(new Path(".settings"));
        if (!folder.exists())
        {
            folder.create(false, true, null);
        }
        
        final IFile file = folder.getFile(
                new Path("org.eclipse.jst.jsf.designtime.appmgr.prefs"));
        
        if (!file.exists())
        {
            file.create(new ByteArrayInputStream(new byte[0]), false, null);
        }
        
        return file;
    }
}
