/*******************************************************************************
 * 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.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);
    }
}
