/*******************************************************************************
 * 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 TLDRegistryPreferences                                     _prefs;

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

        _prefs = new TLDRegistryPreferences(JSFCorePlugin.getDefault().getPreferenceStore());
        _prefs.load();
        final IdentifierOrderedIteratorPolicy<String> policy =
            getTagResolvingPolicy();
        // 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<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);
        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)
    {
        final CMDocumentFactoryTLD factory = new CMDocumentFactoryTLD();
        final TLDDocument doc = (TLDDocument) factory
                .createCMDocument(tagRecord);

        final TLDNamespace ns = _nsResolved.remove(doc.getUri());

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