/*******************************************************************************
 * 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.model.jsp.registry;

import java.io.IOException;
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.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.jst.jsf.common.internal.managedobject.IManagedObject;
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.Messages;
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.designtime.internal.view.model.jsp.DefaultJSPTagResolver;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDNamespace;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TagIntrospectingStrategy;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.UnresolvedJSPTagResolvingStrategy;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.persistence.PersistedDataTagStrategy;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.CMDocumentFactoryTLD;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDDocument;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDElementDeclaration;
import org.eclipse.jst.jsp.core.taglib.ITLDRecord;
import org.eclipse.jst.jsp.core.taglib.ITaglibRecord;
import org.eclipse.jst.jsp.core.taglib.TaglibIndex;

/**
 * Registry of all tld-defined tags for a particular project classpath
 * 
 * @author cbateman
 * 
 */
public final class TLDTagRegistry extends AbstractTagRegistry implements
        IManagedObject
{
    // INSTANCE
    private final IProject                                             _project;
    private final Map<String, TLDNamespace>                            _nsResolved;
    private final CompositeTagResolvingStrategy<TLDElementDeclaration> _resolver;
    private boolean                                                    _hasBeenInitialized = false;
    private final ConcurrentLinkedQueue<LibraryOperation>              _changeOperations   = new ConcurrentLinkedQueue<LibraryOperation>();
    private final Job                                                  _changeJob;
    private final PersistedDataTagStrategy                             _persistedTagStrategy;
    private TagIndexListener                                           _tagIndexListener;
    private final TLDRegistryPreferences                               _prefs;
    private final MyPropertyListener                                   _myPropertyListener;

    TLDTagRegistry(final IProject project)
    {
        _project = project;
        _nsResolved = new HashMap<String, TLDNamespace>();

        _prefs = new TLDRegistryPreferences(JSFCorePlugin.getDefault().getPreferenceStore());
        _myPropertyListener = new MyPropertyListener();
        _prefs.addListener(_myPropertyListener);
        _prefs.load();
        final IdentifierOrderedIteratorPolicy<String> policy =
            getTagResolvingPolicy();

        _resolver = new CompositeTagResolvingStrategy<TLDElementDeclaration>(
                policy);

        // add the strategies
        _resolver.addStrategy(new TagIntrospectingStrategy(_project));
        _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());
        _persistedTagStrategy = new PersistedDataTagStrategy(_project);
        _persistedTagStrategy.init();
        _resolver.addStrategy(_persistedTagStrategy);

        _changeJob = new ChangeJob(project.getName());
    }

    private IdentifierOrderedIteratorPolicy<String>  getTagResolvingPolicy()
    {
        // strategy ordering
        final List<String>  prefOrdering = _prefs.getEnabledIds();
        final List<String> strategyOrdering = new ArrayList<String>(prefOrdering);
        
        // this strategy must always be here, always last
        strategyOrdering.add(UnresolvedJSPTagResolvingStrategy.ID);

        final IdentifierOrderedIteratorPolicy<String> policy = new IdentifierOrderedIteratorPolicy<String>(
                strategyOrdering);
        // 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);
        return  policy;
    }

    protected final void doDispose()
    {
        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
        {
            JSFCoreTraceOptions.log("TLDTagRegistry: Disposing for project " //$NON-NLS-1$
                    + _project.toString());
        }

        // call checkpoint to flush serializable data
        checkpoint();
        //_persistedTagStrategy.dispose();

        _prefs.removeListener(_myPropertyListener);
        _prefs.dispose();

        _nsResolved.clear();
        _changeOperations.clear();

        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
        {
            JSFCoreTraceOptions
                    .log("TLDTagRegistry: Done disposing registry for " //$NON-NLS-1$
                            + _project.toString());
        }
    }

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

    public synchronized void checkpoint()
    {
        try
        {
            _persistedTagStrategy.save(_nsResolved);
        }
        catch (IOException e)
        {
           JSFCorePlugin.log(e, "Checkpointing JSP tags failed"); //$NON-NLS-1$
        }
        catch (ClassNotFoundException e)
        {
            JSFCorePlugin.log(e, "Checkpointing JSP tags failed"); //$NON-NLS-1$
        }
    }

    @Override
    protected Job getRefreshJob(final boolean flushCaches)
    {
        return new Job(Messages.TLDTagRegistry_RefreshJob + _project.getName())
        {
            @Override
            protected IStatus run(final IProgressMonitor monitor)
            {
                if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
                {
                    JSFCoreTraceOptions.log("TLDTagRegistry.refresh: start"); //$NON-NLS-1$
                }

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

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

                    if (flushCaches)
                    {
                        _persistedTagStrategy.clear();
                    }
                    // 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(TLDTagRegistry.this,
                            TagRegistryChangeEvent.EventType.REMOVED_NAMESPACE,
                            namespaces));
                    initialize(true);

                    if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
                    {
                        JSFCoreTraceOptions
                                .log("TLDTagRegistry.refresh: finished"); //$NON-NLS-1$
                    }
                    return Status.OK_STATUS;
                }
            }
        };
    }

    /**
     */
    private void initialize(boolean fireEvent)
    {
        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
        {
            JSFCoreTraceOptions.log("TLDTagRegistry.initialize: start"); //$NON-NLS-1$
        }

        final ITaglibRecord[] tldrecs = TaglibIndex
                .getAvailableTaglibRecords(_project.getFullPath());
        final List<Namespace> affectedObjects = new ArrayList<Namespace>();
        for (final ITaglibRecord tldrec : tldrecs)
        {
            // defer the event
            final Namespace ns = initialize(tldrec, fireEvent);

            if (ns != null)
            {
                affectedObjects.add(ns);
            }
        }

        _hasBeenInitialized = true;

        // if tag index listener does exist, add it
        if (_tagIndexListener == null)
        {
            if (JSFCoreTraceOptions.TRACE_TLDREGISTRYMANAGER)
            {
                JSFCoreTraceOptions
                        .log("TLDRegistryManager: installing tag index listener due to create instance for " //$NON-NLS-1$
                                + _project.toString());
            }

            _tagIndexListener = new TagIndexListener(this);
            TaglibIndex.addTaglibIndexListener(_tagIndexListener);
        }

        // if (affectedObjects.size() > 0)
        // {
        // fireEvent(new TagRegistryChangeEvent(this,
        // TagRegistryChangeEvent.EventType.ADDED_NAMESPACE,
        // affectedObjects));
        // }

        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
        {
            JSFCoreTraceOptions.log("TLDTagRegistry.initialize: finished"); //$NON-NLS-1$
        }
    }

    TLDNamespace initialize(final ITaglibRecord tagRecord,
            final boolean fireEvent)
    {
        if (tagRecord.getRecordType() == ITLDRecord.URL)
        {
            if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY_CHANGES)
            {
                JSFCoreTraceOptions.log("TLDTagRegistry.initialize_TagRecord: Initializing new tld record: "+tagRecord.toString()); //$NON-NLS-1$
            }
            long startTime = 0;
            
            if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY_PERF)
            {
                startTime = System.nanoTime();
            }
            
            final CMDocumentFactoryTLD factory = new CMDocumentFactoryTLD();
            final TLDDocument doc = (TLDDocument) factory
                    .createCMDocument(tagRecord);
            if (doc != null)
            {
                final TLDNamespace ns = new TLDNamespace(doc, _resolver);
                _nsResolved.put(doc.getUri(), ns);
    
                if (fireEvent)
                {
                    fireEvent(new TagRegistryChangeEvent(this,
                            TagRegistryChangeEvent.EventType.ADDED_NAMESPACE,
                            Collections.singletonList(ns)));
                }

                if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY_PERF)
                {
                    System.out.printf("Time to update namespace %s was %d\n", //$NON-NLS-1$
                            ns.getNSUri(), Long.valueOf(System.nanoTime()
                                    - startTime));
                }
                return ns;
            }
        }
        else 
        {
            if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY_CHANGES)
            {
                JSFCoreTraceOptions.log("TLDTagRegistry.initialize_TagRecord: Skipping tag record for "+tagRecord.toString()); //$NON-NLS-1$
            }

        }
        // no new namespace
        return null;
    }

    void remove(final ITaglibRecord tagRecord)
    {
        // this is safer, since we likely fail to create a TLDDocument for
        // a tagRecord that has been removed.
        final String uri = tagRecord.getDescriptor().getURI();
        final TLDNamespace ns = _nsResolved.remove(uri);

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

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jst.jsf.designtime.internal.view.model.jsp.registry.ITagRegistry#getAllTagLibraries()
     */
    public final synchronized Collection<? extends Namespace> getAllTagLibraries()
    {
        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
        {
            JSFCoreTraceOptions.log("TLDTagRegistry.getAllTagLibraries: start"); //$NON-NLS-1$
        }
        long startTime = 0;
        
        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY_PERF)
        {
            startTime = System.nanoTime();
        }
        
        if (!_hasBeenInitialized)
        {
            initialize(false);
        }

        final Set<TLDNamespace> allTagLibraries = new HashSet<TLDNamespace>();
        allTagLibraries.addAll(_nsResolved.values());

        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY_PERF)
        {
            System.out.println("Time to getAllTagLibraries for JSP: "+(System.nanoTime()-startTime)); //$NON-NLS-1$
        }
        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
        {
            JSFCoreTraceOptions
                    .log("TLDTagRegistry.getAllTagLibraries: finished"); //$NON-NLS-1$
        }
        return allTagLibraries;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jst.jsf.designtime.internal.view.model.jsp.registry.ITagRegistry#getTagLibrary(java.lang.String)
     */
    public final synchronized Namespace getTagLibrary(final String uri)
    {
        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
        {
            JSFCoreTraceOptions.log("TLDTagRegistry.getTagLibrary: start uri=" //$NON-NLS-1$
                    + uri);
        }

        if (!_hasBeenInitialized)
        {
            initialize(false);
        }

        final Namespace ns = _nsResolved.get(uri);

        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
        {
            JSFCoreTraceOptions
                    .log("TLDTagRegistry.getTagLibrary: finished, result=" //$NON-NLS-1$
                            + ns.toString());
        }
        return ns;
    }

    @Override
    public String toString()
    {
        return String
                .format(
                        "TLDRegistry for project %s, isDisposed=%s, hasBeenInitialized=%s, numberOfNamespace=%d", //$NON-NLS-1$
                        _project.toString(), Boolean.valueOf(isDisposed()),
                        Boolean.valueOf(_hasBeenInitialized), Integer
                                .valueOf(_nsResolved.size()));
    }

    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(Messages.TLDTagRegistry_UpdateJob + projectName); 
        }

        @Override
        protected IStatus run(final IProgressMonitor monitor)
        {
            synchronized (TLDTagRegistry.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;
            }
        }
    }
    
    private class MyPropertyListener extends TLDRegistryPreferences.PropertyListener
    {
        @Override
        public void strategyOrderChanged()
        {
            synchronized(TLDTagRegistry.this)
            {
                _prefs.load();
                final IdentifierOrderedIteratorPolicy<String> policy =
                    getTagResolvingPolicy();
                _resolver.setPolicy(policy);
            }
        }
    }
}
