/*******************************************************************************
 * 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.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 "
                    + _project.toString());
        }

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

        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
        {
            JSFCoreTraceOptions
                    .log("TLDTagRegistry: Done disposing registry for "
                            + _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");
        }
        catch (ClassNotFoundException e)
        {
            JSFCorePlugin.log(e, "Checkpointing JSP tags failed");
        }
    }

    @Override
    protected Job getRefreshJob(final boolean flushCaches)
    {
        return new Job("Refreshing JSP tag registry for " + _project.getName())
        {
            @Override
            protected IStatus run(final IProgressMonitor monitor)
            {
                if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
                {
                    JSFCoreTraceOptions.log("TLDTagRegistry.refresh: start");
                }

                synchronized (TLDTagRegistry.this)
                {
                    if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
                    {
                        JSFCoreTraceOptions
                                .log("TLDTagRegistry.refresh: start");
                    }

                    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");
                    }
                    return Status.OK_STATUS;
                }
            }
        };
    }

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

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

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

        }
        // 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");
        }
        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));
        }
        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
        {
            JSFCoreTraceOptions
                    .log("TLDTagRegistry.getAllTagLibraries: finished");
        }
        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="
                    + uri);
        }

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

        final Namespace ns = _nsResolved.get(uri);

        if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY)
        {
            JSFCoreTraceOptions
                    .log("TLDTagRegistry.getTagLibrary: finished, result="
                            + ns.toString());
        }
        return ns;
    }

    @Override
    public String toString()
    {
        return String
                .format(
                        "TLDRegistry for project %s, isDisposed=%s, hasBeenInitialized=%s, numberOfNamespace=%d",
                        _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("Update job for project " + 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",
                        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);
            }
        }
    }
}
