/*******************************************************************************
 * Copyright (c) 2008 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 - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.facelet.core.internal.registry.taglib;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.concurrent.CopyOnWriteArrayList;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jst.j2ee.common.ParamValue;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.j2ee.web.componentcore.util.WebArtifactEdit;
import org.eclipse.jst.j2ee.webapplication.ContextParam;
import org.eclipse.jst.j2ee.webapplication.WebApp;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.jsfappconfig.JSFAppConfigUtils;
import org.eclipse.jst.jsf.facelet.core.internal.FaceletCorePlugin;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.WebappConfiguration.WebappListener.WebappChangeEvent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;

/**
 * Manages the web.xml elements of interest to Facelet tag libraries
 * 
 * @author cbateman
 * 
 */
public class WebappConfiguration
{
    // TODO: move these to jsf core.
    private static final String FACELET_10_LIBRARIES_CONTEXT_PARAM_NAME = "facelets.LIBRARIES"; //$NON-NLS-1$
    private static final String JSF20_FACELET_LIBRARIES_CONTEXT_PARAM_NAME = "javax.faces.FACELETS_LIBRARIES"; //$NON-NLS-1$
    private final IProject      _project;
    /**
     * Cached instance of ContextParamAdapter.
     */
    private final ContextParamAdapter _contextParamAdapter;
    private List<IFile>         _cachedFiles;

    /**
     * @param project
     */
    /*package*/ WebappConfiguration(final IProject project)
    {
        _project = project;
        _contextParamAdapter = new ContextParamAdapter();
    }

    /**
     * @param listener
     */
    public void addListener(final WebappListener listener)
    {
        _contextParamAdapter.addListener(listener);
    }
    
    /**
     * @param listener
     */
    public void removeListener(final WebappListener listener)
    {
        _contextParamAdapter.removeListener(listener);
    }

    /**
     * @return the list of IFile's 
     */
    public List<IFile> getFiles()
    {
        final IVirtualFolder folder = JSFAppConfigUtils
                .getWebContentFolder(_project);

        if (folder == null)
        {
            return Collections.emptyList();
        }

        final List<String> filenames = getConfigFilesFromContextParam(_project);
        final List<IFile> files = new ArrayList<IFile>();

        for (final String filename : filenames)
        {
            final IVirtualFile vfile = folder.getFile(new Path(filename));
            if (vfile != null)
            {
                files.add(vfile.getUnderlyingFile());
            }
        }
        _cachedFiles = files;
        return Collections.unmodifiableList(files);
    }

    private Object getModelObject()
    {
        final IModelProvider provider = ModelProviderManager
                .getModelProvider(_project);
        return provider.getModelObject();
    }

    /**
     * 
     */
    public void start()
    {
        final Object webAppObj = getModelObject();
        if (webAppObj != null)
        {
            if (webAppObj instanceof WebApp)
            {
                startLocatingJ2EEConfigs((WebApp) webAppObj);
            }
            else if (webAppObj instanceof org.eclipse.jst.javaee.web.WebApp)
            {
                startLocatingJEEConfigs((org.eclipse.jst.javaee.web.WebApp) webAppObj);
            }
        }
        else
        {
            FaceletCorePlugin
                    .log(
                            "Could not get webApp for project: " + _project, new Exception()); //$NON-NLS-1$
        }
    }

    /**
     * 
     */
    public void dispose()
    {
        if (_contextParamAdapter != null)
        {
            final Object webAppObj = getModelObject();
            if (webAppObj != null)
            {
                if (webAppObj instanceof WebApp)
                {
                    stopLocatingJ2EEConfigs((WebApp) webAppObj);
                }
                else if (webAppObj instanceof org.eclipse.jst.javaee.web.WebApp)
                {
                    stopLocatingJEEConfigs((org.eclipse.jst.javaee.web.WebApp) webAppObj);
                }
            }
            else
            {
                FaceletCorePlugin
                        .log(
                                "Failed stopping locator for project: " + _project.getName() //$NON-NLS-1$
                                , new Exception());
            }
            //_contextParamAdapter.dispose();
        }
    }

    private void startLocatingJ2EEConfigs(final WebApp webApp)
    {
        webApp.eAdapters().add(_contextParamAdapter);
        final EList contexts = webApp.getContexts();
        if (contexts != null)
        {
            final Iterator itContexts = contexts.iterator();
            while (itContexts.hasNext())
            {
                final ContextParam contextParam = (ContextParam) itContexts
                        .next();
                contextParam.eAdapters().add(_contextParamAdapter);
            }
        }
        final EList contextParams = webApp.getContextParams();
        if (contextParams != null)
        {
            final Iterator itContextParams = contextParams.iterator();
            while (itContextParams.hasNext())
            {
                final ParamValue paramValue = (ParamValue) itContextParams
                        .next();
                paramValue.eAdapters().add(_contextParamAdapter);
            }
        }
    }

    private void startLocatingJEEConfigs(
            final org.eclipse.jst.javaee.web.WebApp webApp)
    {
        ((EObject) webApp).eAdapters().add(_contextParamAdapter);
        // System.out.println(((EObject)webApp).eDeliver());
        final List params = webApp.getContextParams();
        if (params != null)
        {
            final Iterator itContexts = params.iterator();
            while (itContexts.hasNext())
            {
                final EObject contextParam = (EObject) itContexts.next();
                contextParam.eAdapters().add(_contextParamAdapter);
            }
        }
    }

    private void stopLocatingJ2EEConfigs(final WebApp webApp)
    {
        webApp.eAdapters().remove(_contextParamAdapter);
        final EList contexts = webApp.getContexts();
        if (contexts != null)
        {
            final Iterator itContexts = contexts.iterator();
            while (itContexts.hasNext())
            {
                final ContextParam contextParam = (ContextParam) itContexts
                        .next();
                contextParam.eAdapters().remove(_contextParamAdapter);
            }
        }
        final EList contextParams = webApp.getContextParams();
        if (contextParams != null)
        {
            final Iterator itContextParams = contextParams.iterator();
            while (itContextParams.hasNext())
            {
                final ParamValue paramValue = (ParamValue) itContextParams
                        .next();
                paramValue.eAdapters().remove(_contextParamAdapter);
            }
        }
    }

    private void stopLocatingJEEConfigs(
            final org.eclipse.jst.javaee.web.WebApp webApp)
    {
        ((EObject) webApp).eAdapters().remove(_contextParamAdapter);
        final List contextParams = webApp.getContextParams();
        if (contextParams != null)
        {
            final Iterator itContextParams = contextParams.iterator();
            while (itContextParams.hasNext())
            {
                final EObject paramValue = (EObject) itContextParams.next();
                paramValue.eAdapters().remove(_contextParamAdapter);
            }
        }
    }

    /**
     * Gets list of application configuration file names as listed in the JSF
     * CONFIG_FILES context parameter ("javax.faces.CONFIG_FILES"). Will return
     * an empty list if WebArtifactEdit is null, if WebApp is null, if context
     * parameter does not exist, or if trimmed context parameter's value is an
     * empty String.
     * 
     * @param project
     *            IProject instance for which to get the context parameter's
     *            value.
     * @return List of application configuration file names as listed in the JSF
     *         CONFIG_FILES context parameter ("javax.faces.CONFIG_FILES"); list
     *         may be empty.
     */
    public static List<String> getConfigFilesFromContextParam(
            final IProject project)
    {
        List<String> filesList = Collections.EMPTY_LIST;
        if (JSFAppConfigUtils.isValidJSFProject(project))
        {
            final IModelProvider provider = ModelProviderManager
                    .getModelProvider(project);
            final Object webAppObj = provider.getModelObject();
            if (webAppObj != null)
            {
                if (webAppObj instanceof WebApp)
                {
                    filesList = getConfigFilesForJ2EEApp(project);
                }
                else if (webAppObj instanceof org.eclipse.jst.javaee.web.WebApp)
                {
                    filesList = getConfigFilesForJEEApp((org.eclipse.jst.javaee.web.WebApp) webAppObj);
                }
            }

        }
        return filesList;
    }

    private static List<String> getConfigFilesForJEEApp(
            final org.eclipse.jst.javaee.web.WebApp webApp)
    {
        String filesString = null;
        final List contextParams = webApp.getContextParams();
        final Iterator itContextParams = contextParams.iterator();
        while (itContextParams.hasNext())
        {
            final org.eclipse.jst.javaee.core.ParamValue paramValue = (org.eclipse.jst.javaee.core.ParamValue) itContextParams
                    .next();
            if (paramValue.getParamName().equals(
                    FACELET_10_LIBRARIES_CONTEXT_PARAM_NAME)||
                    paramValue.getParamName().equals(
                            JSF20_FACELET_LIBRARIES_CONTEXT_PARAM_NAME))
            {
                filesString = paramValue.getParamValue();
                break;
            }
        }
        return parseFilesString(filesString);
    }

    private static List<String> getConfigFilesForJ2EEApp(final IProject project)
    {
        List filesList = new ArrayList();
        final WebArtifactEdit webArtifactEdit = WebArtifactEdit
                .getWebArtifactEditForRead(project);
        if (webArtifactEdit != null)
        {
            try
            {
                WebApp webApp = null;
                try
                {
                    webApp = webArtifactEdit.getWebApp();
                }
                catch (final ClassCastException cce)
                {
                    // occasionally thrown from WTP code in RC3 and possibly
                    // later
                    JSFCorePlugin.log(IStatus.ERROR, cce.getLocalizedMessage(),
                            cce);
                    return filesList;
                }
                if (webApp != null)
                {
                    String filesString = null;
                    // need to branch here due to model version differences
                    // (BugZilla #119442)
                    if (webApp.getVersionID() == J2EEVersionConstants.WEB_2_3_ID)
                    {
                        final EList contexts = webApp.getContexts();
                        final Iterator itContexts = contexts.iterator();
                        while (itContexts.hasNext())
                        {
                            final ContextParam contextParam = (ContextParam) itContexts
                                    .next();
                            if (contextParam.getParamName().equals(
                                    FACELET_10_LIBRARIES_CONTEXT_PARAM_NAME)||
                                    contextParam.getParamName().equals(
                                            JSF20_FACELET_LIBRARIES_CONTEXT_PARAM_NAME))
                           // 	if (contextParam.getParamName().equals(
                           //        FACELET_LIBRARIES_CONTEXT_PARAM_NAME))
                            {
                                filesString = contextParam.getParamValue();
                                break;
                            }
                        }
                    }
                    else
                    {
                        final EList contextParams = webApp.getContextParams();
                        final Iterator itContextParams = contextParams
                                .iterator();
                        while (itContextParams.hasNext())
                        {
                            final ParamValue paramValue = (ParamValue) itContextParams
                                    .next();
                            if (paramValue.getName().equals(
                                    FACELET_10_LIBRARIES_CONTEXT_PARAM_NAME)||
                                    paramValue.getName().equals(
                                            JSF20_FACELET_LIBRARIES_CONTEXT_PARAM_NAME))
                       //    if (paramValue.getName().equals(
                       //             FACELET_LIBRARIES_CONTEXT_PARAM_NAME))
                            {
                                filesString = paramValue.getValue();
                                break;
                            }
                        }
                    }
                    filesList = parseFilesString(filesString);
                }
            }
            finally
            {
                webArtifactEdit.dispose();
            }
        }

        return filesList;
    }

    private static List parseFilesString(final String filesString)
    {
        final List filesList = new ArrayList();
        if (filesString != null && filesString.trim().length() > 0)
        {
            final StringTokenizer stFilesString = new StringTokenizer(
                    filesString, ";"); //$NON-NLS-1$
            while (stFilesString.hasMoreTokens())
            {
                final String configFile = stFilesString.nextToken().trim();
                filesList.add(configFile);
            }
        }
        return filesList;
    }

    /**
     * Adapter implementation used to monitor addition/removal of context-param
     * nodes and change in name of existing nodes in order to respond to changes
     * to the JSF CONFIG_FILES context-param.
     * 
     * @author Ian Trimble - Oracle
     */
    private class ContextParamAdapter extends AdapterImpl
    {
        private final CopyOnWriteArrayList<WebappListener> _listeners = new CopyOnWriteArrayList<WebappListener>();

        public void addListener(final WebappListener listener)
        {
            _listeners.addIfAbsent(listener);
        }

        public void removeListener(final WebappListener listener)
        {
            _listeners.remove(listener);
        }

        private void fireEvent(final WebappChangeEvent event)
        {
            for (final WebappListener listener : _listeners)
            {
                listener.webappChanged(event);
            }
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.
         * eclipse.emf.common.notify.Notification)
         */
        @Override
        public void notifyChanged(final Notification notification)
        {
            final Object objNotifier = notification.getNotifier();
            // System.out.println(objNotifier.toString());
            if (objNotifier instanceof WebApp
                    || objNotifier instanceof org.eclipse.jst.javaee.web.WebApp)
            {
                final int eventType = notification.getEventType();
                switch (eventType)
                {
                    case Notification.ADD:
                        final Object objNewValue = notification.getNewValue();
                        if (objNewValue instanceof ContextParam
                                || objNewValue instanceof org.eclipse.jst.javaee.core.ParamValue)
                        {
                            contextParamAdded((EObject) objNewValue);
                        }
                        else if (objNewValue instanceof ParamValue)
                        {
                            paramValueAdded((EObject) objNewValue);
                        }
                    break;
                    case Notification.REMOVE:
                        final Object objOldValue = notification.getOldValue();
                        if (objOldValue instanceof ContextParam
                                || objOldValue instanceof org.eclipse.jst.javaee.core.ParamValue)
                        {
                            contextParamRemoved((EObject) objOldValue);
                        }
                        else if (objOldValue instanceof ParamValue)
                        {
                            paramValueRemoved((EObject) objOldValue);
                        }
                    break;
                }
            }
            // else if (objNotifier instanceof ContextParam
            // || objNotifier instanceof org.eclipse.jst.javaee.core.ParamValue)
            // {
            // if (notification.getEventType() != Notification.REMOVING_ADAPTER)
            // {
            // _listener
            // .tagLibChanged(ContextParamSpecifiedFaceletTaglibLocator.this);
            // }
            // }
            // else if (objNotifier instanceof ParamValue)
            // {
            // if (notification.getEventType() != Notification.REMOVING_ADAPTER)
            // {
            // _listener
            // .tagLibChanged(ContextParamSpecifiedFaceletTaglibLocator.this);
            // }
            // }
        }

        /**
         * Called when a new ContextParam instance is added.
         * 
         * @param contextParam
         *            ContextParam instance.
         */
        protected void contextParamAdded(final EObject contextParam)
        {
            if (isConfigFilesContextParam(contextParam))
            {
                checkAndFireFileChanges();
            }
            contextParam.eAdapters().add(this);
        }

        private void checkAndFireFileChanges()
        {
            final List<IFile> oldFiles = _cachedFiles;
            final List<IFile> newFiles = getFiles();

            final List<IFile> filesAdded = new ArrayList<IFile>();
            final List<IFile> filesRemoved = new ArrayList<IFile>();

            for (final IFile oldFile : oldFiles)
            {
                if (!newFiles.contains(oldFile))
                {
                    filesRemoved.add(oldFile);
                }
            }

            for (final IFile newFile : newFiles)
            {
                if (!oldFiles.contains(newFile))
                {
                    filesAdded.add(newFile);
                }
            }

            if (filesAdded.size() > 0 || filesRemoved.size() > 0)
            {
                fireEvent(new WebappChangeEvent(filesRemoved, filesAdded));
            }
        }

        /**
         * Called when a new ParamValue instance is added.
         * 
         * @param paramValue
         *            ParamValue instance.
         */
        protected void paramValueAdded(final EObject paramValue)
        {
            if (isConfigFilesParamValue(paramValue))
            {
                checkAndFireFileChanges();
            }
            paramValue.eAdapters().add(this);
        }

        /**
         * Called when a ContextParam instance is removed.
         * 
         * @param contextParam
         *            ContextParam instance.
         */
        protected void contextParamRemoved(final EObject contextParam)
        {
            if (isConfigFilesContextParam(contextParam))
            {
                checkAndFireFileChanges();
            }
            contextParam.eAdapters().remove(this);
        }

        /**
         * Called when a ParamValue instance is removed.
         * 
         * @param paramValue
         *            ParamValue instance.
         */
        protected void paramValueRemoved(final EObject paramValue)
        {
            if (isConfigFilesParamValue(paramValue))
            {
                checkAndFireFileChanges();
            }
            paramValue.eAdapters().remove(this);
        }

        /**
         * Tests if the passed ContextParam instance is the JSF CONFIG_FILES
         * context parameter.
         * 
         * @param contextParam
         *            ContextParam instance.
         * @return true if the passed ContextParam instance is the JSF
         *         CONFIG_FILES context parameter, else false
         */
        protected boolean isConfigFilesContextParam(final EObject contextParam)
        {
            boolean isConfigFiles = false;
            if (contextParam != null)
            {
                String name = null;
                if (contextParam instanceof ContextParam)
                {
                    name = ((ContextParam) contextParam).getParamName();
                }
                else if (contextParam instanceof org.eclipse.jst.javaee.core.ParamValue)
                {
                    name = ((org.eclipse.jst.javaee.core.ParamValue) contextParam)
                            .getParamName();
                }

                if (FACELET_10_LIBRARIES_CONTEXT_PARAM_NAME.equals(name)||
                        JSF20_FACELET_LIBRARIES_CONTEXT_PARAM_NAME.equals(name))
                {
                    isConfigFiles = true;
                }
            }
            return isConfigFiles;
        }

        /**
         * Tests if the passed ParamValue instance is the JSF CONFIG_FILES
         * context parameter.
         * 
         * @param paramVal
         *            as EObject ParamValue instance.
         * @return true if the passed ParamValue instance is the JSF
         *         CONFIG_FILES context parameter, else false
         */
        protected boolean isConfigFilesParamValue(final EObject paramVal)
        {
            boolean isConfigFiles = false;
            if (paramVal != null)
            {
                String name = null;
                if (paramVal instanceof ParamValue)
                {
                    name = ((ParamValue) paramVal).getName();
                }
                else if (paramVal instanceof org.eclipse.jst.javaee.core.ParamValue)
                {
                    name = ((org.eclipse.jst.javaee.core.ParamValue) paramVal)
                            .getParamName();
                }

                if (FACELET_10_LIBRARIES_CONTEXT_PARAM_NAME.equals(name)||
                        JSF20_FACELET_LIBRARIES_CONTEXT_PARAM_NAME.equals(name))
                {
                    isConfigFiles = true;
                }
            }
            return isConfigFiles;
        }
    }

    abstract static class WebappListener
    {
        public static class WebappChangeEvent
        {
            private final List<IFile> _removed;
            private final List<IFile> _added;

            WebappChangeEvent(final List<IFile> removed, final List<IFile> added)
            {
                _removed = Collections.unmodifiableList(removed);
                _added = Collections.unmodifiableList(added);
            }

            public final List<IFile> getRemoved()
            {
                return _removed;
            }

            public final List<IFile> getAdded()
            {
                return _added;
            }
        }

        public abstract void webappChanged(final WebappChangeEvent event);
    }
}
