/*******************************************************************************
 * 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.Namespace;
import org.eclipse.jst.jsf.core.internal.CompositeTagRegistryFactory;
import org.eclipse.jst.jsf.core.internal.TagRegistryFactoryInfo;
import org.eclipse.jst.jsf.designtime.internal.view.model.ITagRegistry;
import org.eclipse.jst.jsf.designtime.internal.view.model.TagRegistryFactory;
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.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<TagRegistryFactoryInfo> factories = CompositeTagRegistryFactory
                    .getInstance().getAllTagRegistryFactories();

            _curTagRegistries.clear();

            for (TagRegistryFactoryInfo 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);
                }
            }
        }
        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("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("Updating namespace")
            {
                @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(),
                                                        "Error updating namespace",
                                                        "There was a problem initializing the namespace");
                                    }
                                }
                            });
                    return Status.OK_STATUS;
                }
            };

            updateNamespaceJob.schedule();

            return new Object[]
            { new TreePlaceholder("Calculating tags, please wait...", null) };
        }
//        else if (parentElement instanceof IJSFTagElement)
//        {
//            return new Object[]
//            { ((IJSFTagElement) parentElement).toString() };
//        }

        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 "
                    + 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, "");
            }

            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 TagRegistryFactoryInfo        _info;
        private final ITagRegistry                  _registry;
        private final Map<String, Namespace>        _namespaces;
        private boolean                             _isUpToDate;

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

        public TagRegistryFactoryInfo 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;
        }

    }
}
