/*******************************************************************************
 * Copyright (c) 2001, 2008 Oracle Corporation and others.
 * 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:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.designtime.internal.view;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jst.jsf.common.internal.JSPUtil;
import org.eclipse.jst.jsf.common.internal.resource.IResourceLifecycleListener;
import org.eclipse.jst.jsf.common.internal.resource.ImmutableLifecycleListener;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent.ReasonType;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.designtime.context.DTFacesContext;
import org.eclipse.jst.jsf.designtime.internal.view.DTUIViewRoot.StalenessAdvisor;
import org.eclipse.jst.jsf.designtime.internal.view.DTUIViewRoot.StalenessEvent;
import org.eclipse.jst.jsf.designtime.internal.view.DTUIViewRoot.StalenessListener;
import org.eclipse.jst.jsf.designtime.internal.view.DTUIViewRoot.VersionStamp;
import org.eclipse.jst.jsf.designtime.internal.view.DTUIViewRoot.StalenessEvent.ChangeType;
import org.eclipse.jst.jsf.designtime.internal.view.model.ITagRegistry;
import org.w3c.dom.Node;

/**
 * A default implementation of the design time view handler meant to parallel
 * the default runtime ViewHandler required by the JSF spec.
 * 
 */
public class DefaultDTViewHandler extends AbstractDTViewHandler
{
    private final MyLifecycleManager _lifecycleManager = new MyLifecycleManager();

    @Override
    public String calculateLocale(final DTFacesContext context)
    throws ViewHandlerException
    {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public IResource getActionDefinition(final DTFacesContext context,
            final String viewId) throws ViewHandlerException
            {
        // TODO: this seems like a bit of a cop out...
        return context.adaptContextObject();
            }

    @Override
    public IPath getActionURL(final DTFacesContext context,
            final IResource resource, final IPath requestPath)
    throws ViewHandlerException
    {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public IPath getRelativeActionPath(final DTFacesContext context,
            final String relativeToViewId, final String uri)
    throws ViewHandlerException
    {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public IViewDefnAdapterFactory getViewMetadataAdapterFactory(
            final DTFacesContext context) throws ViewHandlerException
            {
        final IResource res = context.adaptContextObject();

        if (res instanceof IFile)
        {
            return new DefaultViewDefnAdapterFactory(this);
        }

        return null;
            }

    @Override
    protected VersionStamp createVersionStamp(
            final DTFacesContext facesContext, final String viewId)
    {
        return new TimeBasedVersionStamp();
    }

    static class DefaultViewDefnAdapterFactory extends
    AbstractViewDefnAdapterFactory
    {
        private final DefaultDTViewHandler _myViewHandler;

        DefaultViewDefnAdapterFactory(final DefaultDTViewHandler viewHandler)
        {
            _myViewHandler = viewHandler;
        }

        @Override
        public IViewDefnAdapter<Node, IDocument> createAdapter(
                final DTFacesContext context, final String viewId)
                {
            try
            {
                final IResource res = _myViewHandler.getActionDefinition(
                        context, viewId);

                if (res instanceof IFile)
                {
                    final IFile srcFile = (IFile) res;
                    final ITagRegistry registry = findTagRegistry(srcFile);
                    if (JSPUtil.isJSPContentType(srcFile) && registry != null)
                    {
                        // if we have a jsp file, then return the default
                        // adapter
                        return new JSPViewDefnAdapter(registry);
                    }
                }
            }
            catch (final ViewHandlerException vhe)
            {
                JSFCorePlugin.log(vhe, "While acquiring view adapter");
            }

            // not found or failed
            return null;
                }
    }

    @Override
    protected DTUIViewRoot internalCreateView(
            final DTFacesContext facesContext, final String viewId)
    {
        IViewDefnAdapterFactory factory;
        try
        {
            factory = getViewMetadataAdapterFactory(facesContext);
            if (factory != null)
            {
                final IViewDefnAdapter<?, ?> adapter = factory.createAdapter(
                        facesContext, viewId);
                if (adapter instanceof XMLViewDefnAdapter)
                {
                    final IResource res = facesContext.adaptContextObject();
                    final DTUIViewRoot root = newView(facesContext, viewId);
                    final XMLComponentTreeConstructionStrategy constructionStrategy = createTreeConstructionStrategy(
                            (XMLViewDefnAdapter) adapter, res.getProject());

                    constructionStrategy
                    .createComponentTree(facesContext, root);
                    return root;
                }
                JSFCorePlugin
                .log(
                        IStatus.WARNING,
                        String
                        .format(
                                "Could not get view adapter to construct design time view root for %s",
                                viewId));
            }
            else
            {
                JSFCorePlugin
                .log(
                        IStatus.WARNING,
                        String
                        .format(
                                "Could not get view adapter factory toconstruct design time view root for %s",
                                viewId));
            }
        }
        catch (final ViewHandlerException e)
        {
            JSFCorePlugin.log(e, "While acquiring view defn adapter factory");
            // fall-through
        }

        return new NullViewRoot();
    }

    /**
     * By default, returns DefaultDTUIViewRoot.
     * 
     * @param facesContext
     * @param viewId
     * @return a new instance of a view. Override to change the implementation
     *         or configuration of DTUIViewRoot that is used by
     *         internalCreateView.
     */
    protected DTUIViewRoot newView(final DTFacesContext facesContext,
            final String viewId)
    {
        return new DefaultDTUIViewRoot();
    }

    @Override
    protected void registerView(final DTUIViewRoot viewRoot,
            final DTFacesContext facesContext, final String viewId)
    {
        final IResource res = facesContext.adaptContextObject();
        _lifecycleManager.addViewInfo(viewId, res);
    }

    /**
     * Sub-classes may override to provide a different strategy.
     * 
     * @param adapter
     * @param project
     * @return the construction strategy used to create this view's component
     *         tree
     */
    protected XMLComponentTreeConstructionStrategy createTreeConstructionStrategy(
            final XMLViewDefnAdapter adapter, final IProject project)
    {
        return new XMLComponentTreeConstructionStrategy(adapter, project);
    }

    @Override
    public boolean supportsViewDefinition(final IFile file)
    {
        // currently only JSP content type is supported
        return (JSPUtil.isJSPContentType(file));
    }

    @Override
    protected StalenessAdvisor createStalenessAdvisor(
            final DTUIViewRoot viewRoot, final DTFacesContext facesContext,
            final String viewId)
    {
        final IResource res = facesContext.adaptContextObject();
        // if the view root is null or the res is null fall through
        // and use the null staleness advisor
        if (!(viewRoot instanceof NullViewRoot) && res != null)
        {
            return new ResourceModStampStalenessAdvisor(viewRoot, res, viewId);
        }
        return new NullStalenessAdvisor();
    }

    /**
     * Measures the staleness of a view by comparing the modification stamp on
     * the resource at construction with the current value when isStale is
     * called.
     * 
     * @author cbateman
     * 
     */
    protected final class ResourceModStampStalenessAdvisor extends
    StalenessAdvisor implements Serializable
    {
        /**
         * version id
         */
        private static final long                                 serialVersionUID = -4982206388722638735L;
        private final long                                        _modificationStamp;

        private transient final IResource                         _res;
        private transient final AtomicBoolean                     _forcedStale;
        private transient final StalenessListener                 _myListener;

        /**
         * @param viewRoot
         * @param file
         * @param viewId 
         */
        public ResourceModStampStalenessAdvisor(final DTUIViewRoot viewRoot,
                final IResource file, final String viewId)
        {
            _res = file;
            _modificationStamp = file.getModificationStamp();
            _forcedStale = new AtomicBoolean(false);
            _myListener = new StalenessListener()
            {
                @Override
                protected void stalenessChanged(final StalenessEvent event)
                {
                    if (event.getChangeType() == ChangeType.PROJECT_CLEANED)
                    {
                        if (_forcedStale.compareAndSet(false, true))
                        {
                            _lifecycleManager.removeListener(_res, _myListener);
                        }
                    }
                }
            };
            _lifecycleManager.addViewInfo(viewId, _res);
            _lifecycleManager.addListener(_res, _myListener);
        }

        @Override
        public boolean isStale()
        {
            if (!_forcedStale.get())
            {
                final long curStamp = _res.getModificationStamp();
                return curStamp != _modificationStamp;
            }
            // else forced stale
            return true;
        }

        @Override
        public void addListener(final StalenessListener listener)
        {
            _lifecycleManager.addListener(_res, listener);
        }

        @Override
        public void removeListener(final StalenessListener listener)
        {
            _lifecycleManager.removeListener(_res, listener);
        }

        @Override
        public boolean isAccessible()
        {
            return _res.isAccessible();
        }
    }

    @Override
    public final void setLifecycleListener(final ImmutableLifecycleListener listener)
    {
        _lifecycleManager.update(listener);
    }

    @Override
    protected final void doDispose()
    {
        _lifecycleManager.dispose();
    }

    private class MyLifecycleManager implements IResourceLifecycleListener
    {
        private ImmutableLifecycleListener     _listener;
        private final Map<IResource, ViewInfo> _stalenessListeners;
        private final IResourceChangeListener  _buildListener;

        public MyLifecycleManager()
        {
            _stalenessListeners = new HashMap<IResource, ViewInfo>();
            _buildListener = new IResourceChangeListener()
            {
                // on a clean build request, fire staleness for all project-related
                // resources.
                public void resourceChanged(final IResourceChangeEvent event)
                {
                    if (event.getType() == IResourceChangeEvent.PRE_BUILD)
                    {
                        if (event.getBuildKind() == IncrementalProjectBuilder.CLEAN_BUILD)
                        {
                            if (event.getSource() instanceof IProject)
                            {
                                cleanProject((IProject) event.getSource());
                            }
                            else if (event.getSource() instanceof IWorkspace)
                            {
                                cleanAll();
                            }
                        }
                    }
                }
            };
            ResourcesPlugin.getWorkspace().addResourceChangeListener(_buildListener,
                    IResourceChangeEvent.PRE_BUILD);
        }

        public void addListener(final IResource res, final StalenessListener listener)
        {
            final ViewInfo viewInfo = getViewInfo(res);
            viewInfo.getListeners().addIfAbsent(listener);
        }

        public void removeListener(final IResource res, final StalenessListener listener)
        {
            final ViewInfo viewInfo = getViewInfo(res);
            viewInfo.getListeners().remove(listener);
        }

        public EventResult acceptEvent(final ResourceLifecycleEvent event)
        {
            switch (event.getEventType())
            {
                case RESOURCE_CHANGED:
                {
                    return handleContentChangeEvent(event);
                }

                case RESOURCE_INACCESSIBLE:
                {
                    return handleInaccessibleChangeEvent(event);
                }

                default:
                    // do nothing with other types
            }

            return EventResult.getDefaultEventResult();
        }

        private EventResult handleContentChangeEvent(
                final ResourceLifecycleEvent event)
        {
            if (event.getReasonType() != ReasonType.RESOURCE_CHANGED_CONTENTS)
            {
                return EventResult.getDefaultEventResult();
            }

            final IResource res = event.getAffectedResource();
            final List<StalenessListener> stalenessListeners = getListeners(res);

            if (stalenessListeners != null)
            {
                for (final StalenessListener listener : stalenessListeners)
                {
                    listener.stalenessChanged(new StalenessEvent(
                            ChangeType.VIEW_DEFN_CHANGED));
                }
            }
            return EventResult.getDefaultEventResult();
        }

        private EventResult handleInaccessibleChangeEvent(
                final ResourceLifecycleEvent event)
        {
            final IResource res = event.getAffectedResource();
            final ReasonType reasonType = event.getReasonType();
            ChangeType changeType = null;
            if (reasonType == ReasonType.RESOURCE_PROJECT_CLOSED)
            {
                changeType = ChangeType.VIEW_DEFN_PROJECT_CLOSED;
            }
            else if (reasonType == ReasonType.RESOURCE_DELETED)
            {
                changeType = ChangeType.VIEW_DEFN_DELETED;
            }
            else
            {
                return EventResult.getDefaultEventResult();
            }

            final List<StalenessListener>  listeners = getListeners(res);

            if (listeners != null)
            {
                for (final StalenessListener listener : listeners)
                {
                    listener.stalenessChanged(new StalenessEvent(
                            changeType));
                }
            }
            return EventResult.getDefaultEventResult();
        }

        private void cleanAll()
        {
            final StalenessEvent event = new StalenessEvent(ChangeType.PROJECT_CLEANED);
            for (final Map.Entry<IResource, ViewInfo> entry : _stalenessListeners.entrySet())
            {
                final ViewInfo info = entry.getValue();
                for (final StalenessListener listener : info.getListeners())
                {
                    listener.stalenessChanged(event);
                }
            }
        }

        private void cleanProject(final IProject project)
        {
            final StalenessEvent event = new StalenessEvent(ChangeType.PROJECT_CLEANED);
            for (final Map.Entry<IResource, ViewInfo> entry : _stalenessListeners.entrySet())
            {
                final IResource res = entry.getKey();
                
                if (res.getProject().equals(project))
                {
                    final ViewInfo info = entry.getValue();
                    for (final StalenessListener listener : info.getListeners())
                    {
                        listener.stalenessChanged(event);
                    }
                }
            }
        }

        private List<StalenessListener> getListeners(final IResource res)
        {
            List<StalenessListener> stalenessListeners = null;

            synchronized (this)
            {
                final ViewInfo viewInfo = _stalenessListeners.get(res);

                if (viewInfo != null)
                {
                    stalenessListeners = viewInfo.getListeners();
                }
            }
            return stalenessListeners;
        }

        public synchronized void addViewInfo(final String viewId,
                final IResource res)
        {
            ViewInfo viewInfo = _stalenessListeners.get(res);

            if (viewInfo == null)
            {
                viewInfo = new ViewInfo(viewId);
                _stalenessListeners.put(res, viewInfo);
            }
        }

        public synchronized ViewInfo getViewInfo(final IResource res)
        {
            return _stalenessListeners.get(res);
        }

        public synchronized void dispose()
        {
            // updating with null effectively deregisters any existing listener
            // and doesn't register a new one.
            ResourcesPlugin.getWorkspace().removeResourceChangeListener(_buildListener);
            update(null);
        }

        public synchronized void update(
                final ImmutableLifecycleListener listener)
        {
            if (listener == _listener)
            {
                return;
            }

            final ImmutableLifecycleListener oldListener = _listener;

            if (oldListener != null)
            {
                oldListener.removeListener(this);
            }

            _listener = listener;

            if (_listener != null)
            {
                _listener.addListener(this);
            }
        }
    }

    private static class ViewInfo
    {
        private final CopyOnWriteArrayList<StalenessListener> _listeners;
        private final String                  _viewId;

        /**
         * @param listeners
         * @param res
         */
        private ViewInfo(final String viewId)
        {
            super();
            _listeners = new CopyOnWriteArrayList<StalenessListener>();
            _viewId = viewId;
        }

        protected final CopyOnWriteArrayList<StalenessListener> getListeners()
        {
            return _listeners;
        }

        protected final String getViewId()
        {
            return _viewId;
        }
    }
}
