/*******************************************************************************
 * 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.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.javaee.web.IWebCommon;
import org.eclipse.jst.jsf.common.internal.componentcore.AbstractVirtualComponentQuery;
import org.eclipse.jst.jsf.common.internal.resource.EventResult;
import org.eclipse.jst.jsf.common.internal.resource.IResourceLifecycleListener;
import org.eclipse.jst.jsf.common.internal.resource.LifecycleListener;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent.EventType;
import org.eclipse.jst.jsf.common.internal.resource.WorkspaceMediator;
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
{
    /**
     * The param key for Facelet 1.x libraries declared in web.xml
     */
    public static final String FACELET_10_LIBRARIES_CONTEXT_PARAM_NAME = "facelets.LIBRARIES"; //$NON-NLS-1$
    /**
     * The param key for Facelet 2.0 libraries declared in web.xml
     */
    public 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;
    private final IModelProvider _modelProvider;
    private final AbstractVirtualComponentQuery _vcQuery;
    private final LifecycleListener _lifecycleListener;
    private final WorkspaceMediator _wsMediator;

    /**
     * @param project
     * @param modelProvider
     * @param vcQuery
     * @param wsMediator
     */
    public WebappConfiguration(final IProject project,
            final IModelProvider modelProvider,
            final AbstractVirtualComponentQuery vcQuery,
            final WorkspaceMediator wsMediator)
    {
        _project = project;
        _vcQuery = vcQuery;
        _lifecycleListener = new LifecycleListener(getWebXmlFile(project),
                project.getWorkspace());
        _contextParamAdapter = new ContextParamAdapter();
        _modelProvider = modelProvider;
        _wsMediator = wsMediator;
    }

    /**
     * @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 = _vcQuery.getWebContentFolder(_project);

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

        final List<String> filenames = getConfigFilesFromContextParam(_project,
                _modelProvider);
        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(_cachedFiles);
    }

    private IFile getWebXmlFile(final IProject project)
    {
        final IVirtualFolder webContentFolder = _vcQuery
                .getWebContentFolder(project);
        final IContainer folder = webContentFolder.getUnderlyingFolder();
        return folder.getFile(new Path("WEB-INF/web.xml")); //$NON-NLS-1$
    }

    /**
     * 
     */
    public void start()
    {
        _lifecycleListener.addListener(_contextParamAdapter);
    }

    /**
     * 
     */
    public void stop()
    {
        _lifecycleListener.removeListener(_contextParamAdapter);
    }

    /**
     * 
     */
    public void dispose()
    {
        _lifecycleListener.dispose();
    }

    /**
     * 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.
     * @param provider
     * @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, final IModelProvider provider)
    {
        List<String> filesList = Collections.EMPTY_LIST;
        // if (JSFAppConfigUtils.isValidJSFProject(project))
        {
            final Object webAppObj = provider.getModelObject();
            if (webAppObj != null)
            {
                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();
        final List<String> fileStrings = new ArrayList<String>();
        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();
                fileStrings.addAll(parseFilesString(filesString));
            }
        }
        return fileStrings;
    }

    private static List<String> parseFilesString(final String filesString)
    {
        final List<String> filesList = new ArrayList<String>();
        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 implements IResourceLifecycleListener
    {
        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);
            }
        }

        private void checkAndFireFileChanges()
        {
            final List<IFile> oldFiles = _cachedFiles == null ? Collections.EMPTY_LIST
                    : _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 ContextParam instance is removed.
         * 
         * @param contextParam
         *            ContextParam instance.
         */
        protected void processParamValue(
                final org.eclipse.jst.javaee.core.ParamValue contextParam)
        {
            checkAndFireFileChanges();
        }

//        /**
//         * 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 org.eclipse.jst.javaee.core.ParamValue contextParam)
//        {
//            boolean isConfigFiles = false;
//            if (contextParam != null)
//            {
//                final String name = contextParam.getParamName();
//                if (FACELET_10_LIBRARIES_CONTEXT_PARAM_NAME.equals(name)
//                        || JSF20_FACELET_LIBRARIES_CONTEXT_PARAM_NAME
//                                .equals(name))
//                {
//                    isConfigFiles = true;
//                }
//            }
//            return isConfigFiles;
//        }

        public EventResult acceptEvent(final ResourceLifecycleEvent event)
        {
            // the event is only interesting if it is the web.xml
            if (event.getAffectedResource() instanceof IFile
                    && "web.xml".equals(event.getAffectedResource().getProjectRelativePath().lastSegment())) //$NON-NLS-1$
            {
                if (event.getEventType() == EventType.RESOURCE_CHANGED)
                {
                    handleChange();
                }
            }
            return EventResult.getDefaultEventResult();
        }

        private void handleChange()
        {
            final IWorkspaceRunnable runnable = new IWorkspaceRunnable()
            {
                public void run(final IProgressMonitor monitor) throws CoreException
                {
                    final Object modelObject = _modelProvider.getModelObject();
                    if (modelObject instanceof org.eclipse.jst.javaee.web.WebApp)
                    {
                        for (final org.eclipse.jst.javaee.core.ParamValue paramValue : ((IWebCommon) modelObject)
                                .getContextParams())
                        {
                            processParamValue(paramValue);
                        }
                    }
                    // TODO: possibly handle facelets 1.0 in pre-2.5 webapps in
                    // the
                    // future
                    // if it's worth the complexity.
                    // SEE previous revs in CVS.
                }
            };
            _wsMediator.runInWorkspaceJob(runnable, "Update web xml"); //$NON-NLS-1$
        }
    }

    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);
    }
}
