/*******************************************************************************
 * 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.ui.internal.tagregistry;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.ITagAttribute;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.ITagElement;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.Namespace;
import org.eclipse.jst.jsf.core.internal.CompositeTagRegistryFactory;
import org.eclipse.jst.jsf.core.internal.ITagRegistryFactoryInfo;
import org.eclipse.jst.jsf.designtime.internal.view.model.ITagRegistry;
import org.eclipse.jst.jsf.designtime.internal.view.model.ITagRegistry.TagRegistryChangeEvent;
import org.eclipse.jst.jsf.designtime.internal.view.model.ITagRegistry.TagRegistryChangeEvent.EventType;
import org.eclipse.jst.jsf.designtime.internal.view.model.TagRegistryFactory;
import org.eclipse.jst.jsf.designtime.internal.view.model.TagRegistryFactory.TagRegistryFactoryException;
import org.eclipse.jst.jsf.ui.internal.JSFUiPlugin;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;

/**
 * Structured content provider for tag libraries.
 * 
 * @author cbateman
 * 
 */
public class TaglibContentProvider implements IStructuredContentProvider,
        ITreeContentProvider, ITagRegistry.ITagRegistryListener
{
    private final static Object[]                                     NO_CHILDREN       = new Object[0];
    private IProject                                                  _curInput;
    private Map<ITagRegistry, TagRegistryInstance>                    _curTagRegistries = 
        new HashMap<ITagRegistry, TagRegistryInstance>();
    private Viewer                                                    _curViewer;
    private final AtomicLong                                          _changeStamp      = new AtomicLong(
                                                                                                0);

    public Object[] getElements(final Object inputElement)
    {

        if (inputElement instanceof IProject)
        {
            return _curTagRegistries.values().toArray();
            // return _rootNamespaces.values().toArray();
        }

        return NO_CHILDREN;
    }

    public void dispose()
    {
        // nothing to do
    }

    public void inputChanged(final Viewer viewer, final Object oldInput,
            final Object newInput)
    {
        // update our change stamp to invalid outstanding update tasks
        _changeStamp.incrementAndGet();
        _curViewer = viewer;

        if (oldInput instanceof IProject)
        {
            for (final TagRegistryInstance tagRegistry : _curTagRegistries.values())
            {
                tagRegistry.getRegistry().removeListener(this);
            }
        }

        if (newInput instanceof IProject)
        {
            _curInput = (IProject) newInput;

            final Set<ITagRegistryFactoryInfo> factories = CompositeTagRegistryFactory
                    .getInstance().getAllTagRegistryFactories();

            _curTagRegistries.clear();

            for (ITagRegistryFactoryInfo factoryInfo : factories)
            {
                TagRegistryFactory factory = factoryInfo
                        .getTagRegistryFactory();
                ITagRegistry registry;
                try
                {
                    registry = factory.createTagRegistry(_curInput);
                    if (registry != null)
                    {
                        final TagRegistryInstance registryInstance =
                            new TagRegistryInstance(factoryInfo, registry);
                        _curTagRegistries.put(registry, registryInstance);
                        registry.addListener(this);
                        
                        new UpdateNamespacesListJob(_curInput, _changeStamp.get(), 
                                registryInstance).schedule();
                    }
                }
                catch (TagRegistryFactoryException e)
                {
                    JSFUiPlugin.log(IStatus.ERROR,
                            "Problem getting tag registry", e); //$NON-NLS-1$
                }
            }
        }
        else
        {
            _curInput = null;
            _curTagRegistries.clear();
        }
    }

    public Object[] getChildren(final Object parentElement)
    {
        if (parentElement instanceof IProject)
        {
            return _curTagRegistries.values().toArray();
        }
        else if (parentElement instanceof TagRegistryInstance)
        {
            final TagRegistryInstance regInstance = (TagRegistryInstance) parentElement;
            
            if (!regInstance.isUpToDate())
            {
                return new Object[] {new TreePlaceholder(Messages.TaglibContentProvider_Calculating, null)};
            }
            return regInstance.getNamespaces().values().toArray();
        }
        else if (parentElement instanceof Namespace)
        {
            final Namespace ns = (Namespace) parentElement;

            // this could be very expensive if not initialized
            if (ns.isInitialized())
            {
                return ((Namespace) parentElement).getViewElements().toArray();
            }

            // fire up a job that ensures the namespace is initialized
            // and then fires refresh again on this element
            final Job updateNamespaceJob = new Job(Messages.TaglibContentProvider_JobDesc)
            {
                @Override
                protected IStatus run(final IProgressMonitor monitor)
                {
                    ns.getViewElements();
                    PlatformUI.getWorkbench().getDisplay().asyncExec(
                            new Runnable()
                            {
                                public void run()
                                {
                                    // avoid infinite recursion
                                    if (ns.isInitialized())
                                    {
                                        TaglibContentProvider.this
                                                .viewerRefresh(ns);
                                    }
                                    else
                                    {
                                        MessageDialog
                                                .openError(
                                                        Display
                                                                .getCurrent()
                                                                .getActiveShell(),
                                                        Messages.TaglibContentProvider_NamespaceErrorTitle,
                                                        Messages.TaglibContentProvider_NamespaceErrorDescription);
                                    }
                                }
                            });
                    return Status.OK_STATUS;
                }
            };

            updateNamespaceJob.schedule();

            return new Object[]
            { new TreePlaceholder(Messages.TaglibContentProvider_TagCalculatingWaitMessage, null) };
        }
        else if (parentElement instanceof ITagElement)
        {
            final Map<String, ? extends ITagAttribute> attributes = ((ITagElement)parentElement).getAttributes();
            if (attributes != null)
            {
                return attributes.values().toArray();
            }
        }
        return NO_CHILDREN;
    }

    public Object getParent(final Object element)
    {
        // no support for parent traversal right now
        return null;
    }

    public boolean hasChildren(final Object element)
    {
        // avoid an infinite refresh loop on the namespaces in the tag registry
        if (element instanceof TagRegistryInstance)
        {
            return true;
        }
        // finding all children of a namespace can be expensive
        else if (element instanceof Namespace)
        {
            return ((Namespace) element).hasViewElements();
        }
        return getChildren(element).length > 0;
    }

    public void registryChanged(final TagRegistryChangeEvent changeEvent)
    {
        if (_curViewer != null)
        {
            TagRegistryInstance registryInstance =
                _curTagRegistries.get(changeEvent.getSource());
            
            if (registryInstance != null)
            {
                _curViewer.getControl().getDisplay().asyncExec(
                        new RegistryChangeTask(changeEvent.getType(), changeEvent
                                .getAffectedObjects(), _changeStamp.get(),registryInstance));
            }
        }
    }

    private final class RegistryChangeTask implements Runnable
    {
        private final EventType                 _eventType;
        private final long                      _timestamp;
        private final List<? extends Namespace> _affectedObjects;
        private final TagRegistryInstance       _registryInstance;

        RegistryChangeTask(final TagRegistryChangeEvent.EventType eventType,
                final List<? extends Namespace> affectedObjects,
                final long timestamp, final TagRegistryInstance registryInstance)
        {
            _eventType = eventType;
            _timestamp = timestamp;
            _affectedObjects = affectedObjects;
            _registryInstance = registryInstance;
        }

        public void run()
        {
            // if changes have been made since this task was queued, then abort
            // since we don't know if our data is still valid
            if (_timestamp != TaglibContentProvider.this._changeStamp.get())
            {
                return;
            }

            switch (_eventType)
            {
                case ADDED_NAMESPACE:
                case CHANGED_NAMESPACE:
                {
                    for (final Namespace ns : _affectedObjects)
                    {
                        _registryInstance.getNamespaces().put(ns.getNSUri(), ns);
                    }

                    viewerRefresh(_curInput);
                }
                break;

                case REMOVED_NAMESPACE:
                {
                    for (final Namespace ns : _affectedObjects)
                    {
                        _registryInstance.getNamespaces().remove(ns.getNSUri());
                    }
                    viewerRefresh(_curInput);
                }
                break;

                case REGISTRY_DISPOSED:
                {
                    _registryInstance.getRegistry().removeListener(TaglibContentProvider.this);
                    _curTagRegistries.remove(_registryInstance);
                    viewerRefresh(_curInput);
                }
            }
        }
    }

    private void viewerRefresh(final Object parentElement)
    {
        if (_curViewer instanceof StructuredViewer)
        {
            final StructuredViewer viewer = (StructuredViewer) _curViewer;
            viewer.refresh(parentElement);
        }
        else
        {
            _curViewer.refresh();
        }
    }

    private class UpdateNamespacesListJob extends Job
    {

        private final long                _timestamp;
        private final IProject            _project;
        private final TagRegistryInstance _registry;

        public UpdateNamespacesListJob(final IProject project,
                final long timestamp, final TagRegistryInstance registry)
        {
            super("Updating available namespaces for project " //$NON-NLS-1$
                    + project.getName());
            _project = project;
            _timestamp = timestamp;
            _registry = registry;
        }

        @Override
        protected IStatus run(final IProgressMonitor monitor)
        {
            if (!_project.isAccessible()
                    || _registry.isUpToDate())
            {
                return new Status(IStatus.CANCEL, JSFUiPlugin.PLUGIN_ID, ""); //$NON-NLS-1$
            }

            final Collection<? extends Namespace> libs = _registry.getRegistry()
                    .getAllTagLibraries();
            _registry.getNamespaces().clear();

            for (Namespace ns : libs)
            {
                if (ns.getNSUri() != null)
                {
                    _registry.getNamespaces().put(ns.getNSUri(), ns);

                }
            }

            _registry.setUpToDate(true);
            PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable()
            {
                public void run()
                {
                    // only bother if the provider hasn't changed asynchronously
                    if (_timestamp == TaglibContentProvider.this._changeStamp
                            .get())
                    {
                        viewerRefresh(_curInput);
                    }
                }
            });

            return Status.OK_STATUS;
        }
    }

    static class TagRegistryInstance
    {
        private final ITagRegistryFactoryInfo        _info;
        private final ITagRegistry                  _registry;
        private final Map<String, Namespace>        _namespaces;
        private boolean                             _isUpToDate;

        public TagRegistryInstance(final ITagRegistryFactoryInfo info,
                ITagRegistry registry)
        {
            _info = info;
            _registry = registry;
            _namespaces = new ConcurrentHashMap<String, Namespace>();
        }

        public ITagRegistryFactoryInfo getInfo()
        {
            return _info;
        }

        public ITagRegistry getRegistry()
        {
            return _registry;
        }

        public Map<String, Namespace> getNamespaces()
        {
            return _namespaces;
        }

        public synchronized boolean isUpToDate()
        {
            return _isUpToDate;
        }

        public synchronized void setUpToDate(boolean isUpToDate)
        {
            _isUpToDate = isUpToDate;
        }
    }

    /**
     * Takes the place of a real tree model object while the real object is
     * being retrieved.
     * 
     */
    public static class TreePlaceholder
    {
        private final String _text;
        private final Image  _image;

        TreePlaceholder(final String text, final Image image)
        {
            _text = text;
            _image = image;
        }

        /**
         * @return the placeholder text or null if none
         */
        public String getText()
        {
            return _text;
        }

        /**
         * @return the image or null if none
         */
        public Image getImage()
        {
            return _image;
        }

    }
}
