package org.eclipse.jst.jsf.facelet.core.internal.registry;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.jsf.common.internal.managedobject.IManagedObject;
import org.eclipse.jst.jsf.common.internal.managedobject.ObjectManager.ManagedObjectException;
import org.eclipse.jst.jsf.common.internal.policy.IdentifierOrderedIteratorPolicy;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.Namespace;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.JSFCoreTraceOptions;
import org.eclipse.jst.jsf.designtime.internal.view.model.AbstractTagRegistry;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.CompositeTagResolvingStrategy;
import org.eclipse.jst.jsf.facelet.core.internal.FaceletCorePlugin;
import org.eclipse.jst.jsf.facelet.core.internal.FaceletCoreTraceOptions;
import org.eclipse.jst.jsf.facelet.core.internal.cm.FaceletDocumentFactory;
import org.eclipse.jst.jsf.facelet.core.internal.registry.IFaceletTagResolvingStrategy.TLDWrapper;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.FaceletTagIndex;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.IFaceletTagRecord;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.IProjectTaglibDescriptor;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.Listener;
import org.eclipse.jst.jsf.facelet.core.internal.tagmodel.FaceletNamespace;

/**
 * Registry of all facelet tag registries: at most one per project.
 * 
 */
public final class FaceletTagRegistry extends AbstractTagRegistry implements
        IManagedObject
{
    // INSTANCE
    private final ConcurrentLinkedQueue<LibraryOperation>   _changeOperations = new ConcurrentLinkedQueue<LibraryOperation>();

    private final IProject                                  _project;
    private final Map<String, FaceletNamespace>             _nsResolved;
    private final Set<FaceletNamespace>                     _unResolved;
    private final CompositeTagResolvingStrategy<TLDWrapper> _resolver;
    private final FaceletDocumentFactory                    _factory;
    private final LibraryOperationFactory                   _operationFactory = new LibraryOperationFactory(
                                                                                      this);
    private boolean                                         _isInitialized;

    private ChangeJob                                       _changeJob;
    private MyTaglibListener                                _listener;

    FaceletTagRegistry(final IProject project)
    {
        _project = project;
        _nsResolved = new HashMap<String, FaceletNamespace>();
        _unResolved = new HashSet<FaceletNamespace>();

        final List<String> ids = new ArrayList<String>();
        
//Commenting out this strategy because of current circular dependency with facelet md locating.  See FaceletNamespaceMetaDataLocator.
//        ids.add(FaceletMetaResolvingStrategy.ID);
        ids.add(FaceletTagResolvingStrategy.ID);
        final IdentifierOrderedIteratorPolicy<String> policy = new IdentifierOrderedIteratorPolicy<String>(
                ids);

        // exclude things that are not explicitly listed in the policy. That
        // way preference-based disablement will cause those strategies to
        // be excluded.
        policy.setExcludeNonExplicitValues(true);
        _resolver = new CompositeTagResolvingStrategy<TLDWrapper>(policy);

        _factory = new FaceletDocumentFactory(project);
        // add the strategies
        _resolver.addStrategy(new FaceletTagResolvingStrategy(_project,
                _factory));
        
//Commenting out this strategy because of current circular dependency with facelet md locating.  See FaceletNamespaceMetaDataLocator.
//        _resolver.addStrategy(new FaceletMetaResolvingStrategy(_project, _factory));

        // _resolver.addStrategy(new DefaultJSPTagResolver(_project));
        // makes sure that a tag element will always be created for any
        // given tag definition even if other methods fail
        // _resolver.addStrategy(new UnresolvedJSPTagResolvingStrategy());
        _changeJob = new ChangeJob(project.getName());
    }

    /**
     * @return a copy of all tag libs, both with namespaces resolved and without
     *         Changing the returned may has no effect on the registry, however
     *         the containned objects are not copies.
     */
    @Override
    public synchronized Collection<FaceletNamespace> getAllTagLibraries()
    {
        final Set<FaceletNamespace> allTagLibraries = new HashSet<FaceletNamespace>();
        if (!_isInitialized)
        {
            try
            {
                initialize(false);
                _isInitialized = true;
            }
            catch (final JavaModelException e)
            {
                FaceletCorePlugin.log("Problem during initialization", e); //$NON-NLS-1$
            }
            catch (final CoreException e)
            {
                FaceletCorePlugin.log("Problem during initialization", e); //$NON-NLS-1$
            }
        }
        allTagLibraries.addAll(_nsResolved.values());
        allTagLibraries.addAll(_unResolved);
        return allTagLibraries;
    }

    private void initialize(boolean fireEvent) throws JavaModelException, CoreException
    {
        if (!_project.exists() || !_project.hasNature(JavaCore.NATURE_ID))
        {
            throw new CoreException(new Status(IStatus.ERROR,
                    FaceletCorePlugin.PLUGIN_ID,
                    "Project either does not exists or is not a java project: " //$NON-NLS-1$
                            + _project));
        }

        final FaceletTagIndex index = FaceletTagIndex.getInstance(_project.getWorkspace());

        IProjectTaglibDescriptor tagDesc;
        try
        {
            tagDesc = index.getInstance(_project);
        }
        catch (ManagedObjectException e)
        {
            throw new CoreException(
                    new Status(
                            IStatus.ERROR,
                            FaceletCorePlugin.PLUGIN_ID,
                            "Error instantiating facelet tag index for project: " + _project.getName(), e)); //$NON-NLS-1$
        }

        if (tagDesc != null)
        {
            for (final IFaceletTagRecord taglib : tagDesc.getTagLibraries())
            {
                initialize(taglib, fireEvent);
            }

            _listener = new MyTaglibListener();
            tagDesc.addListener(_listener);
        }
    }

    FaceletNamespace initialize(final IFaceletTagRecord tagRecord,
            final boolean fireEvent)
    {
        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY_CHANGES)
        {
            FaceletCoreTraceOptions
                    .log("TLDTagRegistry.initialize_TagRecord: Initializing new tld record: " + tagRecord.toString()); //$NON-NLS-1$
        }
        final FaceletNamespace ns = new FaceletNamespace(tagRecord, _resolver);
        _nsResolved.put(tagRecord.getURI(), ns);

        if (fireEvent)
        {
            fireEvent(new TagRegistryChangeEvent(this,
                    TagRegistryChangeEvent.EventType.ADDED_NAMESPACE,
                    Collections.singletonList(ns)));
        }
        return ns;
    }

    void remove(final IFaceletTagRecord tagRecord)
    {
        final FaceletNamespace ns = _nsResolved.remove(tagRecord.getURI());

        if (ns != null)
        {
            fireEvent(new TagRegistryChangeEvent(this,
                    TagRegistryChangeEvent.EventType.REMOVED_NAMESPACE,
                    Collections.singletonList(ns)));
        }
    }

    @Override
    public synchronized Namespace getTagLibrary(final String uri)
    {
        // TODO:
        getAllTagLibraries();
        return _nsResolved.get(uri);
    }

    @Override
    protected Job getRefreshJob(final boolean flushCaches)
    {
        return new Job("Refreshing Facelet tag registry for " + _project.getName()) //$NON-NLS-1$
        {
            @Override
            protected IStatus run(final IProgressMonitor monitor)
            {
//                if (FaceletCoreTraceOptions.TRACE_JSPTAGREGISTRY)
//                {
//                    JSFCoreTraceOptions.log("FaceletTagRegistry.refresh: start"); //$NON-NLS-1$
//                }

                synchronized (FaceletTagRegistry.this)
                {
                    if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
                    {
                        JSFCoreTraceOptions
                                .log("FaceletTagRegistry.refresh: start"); //$NON-NLS-1$
                    }

                    final List<Namespace> namespaces = new ArrayList(
                            _nsResolved.values());

                    if (flushCaches)
                    {
                        FaceletTagIndex.getInstance(_project.getWorkspace()).flush(_project);
                    }
                    // if we aren't flushing caches, then check point the
                    // current namespace data, so it isn't lost when we clear
                    // THE NAMESPACES
                    else
                    {
                        checkpoint();
                    }

                    _nsResolved.clear();

                    fireEvent(new TagRegistryChangeEvent(FaceletTagRegistry.this,
                            TagRegistryChangeEvent.EventType.REMOVED_NAMESPACE,
                            namespaces));
                    try
                    {
                        initialize(true);
                    }
                    catch (JavaModelException e)
                    {
                        return new Status(IStatus.ERROR, FaceletCorePlugin.PLUGIN_ID, "Problem refreshing registry", e); //$NON-NLS-1$
                    }
                    catch (CoreException e)
                    {
                        return new Status(IStatus.ERROR, FaceletCorePlugin.PLUGIN_ID, "Problem refreshing registry", e); //$NON-NLS-1$
                    }

//                    if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
//                    {
//                        JSFCoreTraceOptions
//                                .log("TLDTagRegistry.refresh: finished");
//                    }
                    return Status.OK_STATUS;
                }
            }
        };
    }

    private class MyTaglibListener extends Listener
    {
        @Override
        public void changed(TaglibChangedEvent event)
        {
            switch (event.getChangeType())
            {
                case ADDED:
                    addLibraryOperation(_operationFactory
                            .createAddOperation(event.getNewValue()));
                break;
                case CHANGED:
                    addLibraryOperation(_operationFactory
                            .createChangeOperation(event.getNewValue()));
                break;
                case REMOVED:
                    addLibraryOperation(_operationFactory
                            .createRemoveOperation(event.getOldValue()));
                break;
            }
        }
    }

    private void addLibraryOperation(final LibraryOperation operation)
    {
        _changeOperations.add(operation);
        _changeJob.schedule();
    }

    private class ChangeJob extends Job
    {
        private int _rescheduleTime = -1;

        public ChangeJob(final String projectName)
        {
            super("Update job for project " + projectName); //$NON-NLS-1$
        }

        @Override
        protected IStatus run(final IProgressMonitor monitor)
        {
            synchronized (FaceletTagRegistry.this)
            {
                _rescheduleTime = -1;

                LibraryOperation operation = null;
                final MultiStatus multiStatus = new MultiStatus(
                        JSFCorePlugin.PLUGIN_ID, 0, "Result of change job", //$NON-NLS-1$
                        new Throwable());
                while ((operation = _changeOperations.poll()) != null)
                {
                    _rescheduleTime = 10000; // ms

                    operation.run();
                    multiStatus.add(operation.getResult());
                }

                if (_rescheduleTime >= 0 && !monitor.isCanceled())
                {
                    // if any operations were found on this run, reschedule
                    // to run again in 10seconds based on the assumption that
                    // events may be coming in bursts
                    schedule(_rescheduleTime);
                }

                return multiStatus;
            }
        }
    }

    @Override
    protected void doDispose()
    {
        if (_listener != null)
        {
            FaceletTagIndex index = FaceletTagIndex.getInstance(_project.getWorkspace());
            try
            {
                IProjectTaglibDescriptor instance = index.getInstance(_project);
                instance.removeListener(_listener);
            }
            catch (ManagedObjectException e)
            {
                FaceletCorePlugin
                        .log(
                                "Disposing facelet tag registry for project: " + _project.getName(), e); //$NON-NLS-1$
            }

            _nsResolved.clear();
        }
    }

    @Override
    protected void cleanupPersistentState()
    {
        // TODO ??

    }

    public void checkpoint()
    {
        // TODO ??

    }
}
