package org.eclipse.jst.jsf.designtime.internal.resources;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IProject;
import org.eclipse.jst.jsf.common.internal.finder.VisitorMatcher;
import org.eclipse.jst.jsf.common.internal.finder.acceptor.JarEntryMatchingAcceptor;
import org.eclipse.jst.jsf.common.internal.finder.matcher.TaglibJarEntryFinder;
import org.eclipse.jst.jsf.common.internal.locator.ILocatorChangeListener;
import org.eclipse.jst.jsf.common.internal.resource.ClasspathJarFile;
import org.eclipse.jst.jsf.common.internal.resource.ContentTypeResolver;
import org.eclipse.jst.jsf.common.internal.resource.IJarLocator;
import org.eclipse.jst.jsf.common.internal.util.JarUtilities;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;

/**
 * A JSF resource locator that finds resources in jars.
 * 
 * @author cbateman
 * 
 */
public class JarBasedJSFResourceLocator extends AbstractJSFResourceLocator
{
    private final IJarLocator _provider;
    private final ContentTypeResolver _contentTypeResolver;
    private static final Pattern _resourcePathPattern = Pattern
            .compile("META-INF/resources/(.*)"); //$NON-NLS-1$
    private static final TaglibJarEntryFinder _resourceFinder = new TaglibJarEntryFinder(
            _resourcePathPattern);

    /**
     * @param id
     * @param displayName
     * @param noResultValue
     * @param mutableListenerList
     * @param provider
     * @param contentTypeResolver
     */
    public JarBasedJSFResourceLocator(
            final String id,
            final String displayName,
            final List<IJSFResourceFragment> noResultValue,
            final CopyOnWriteArrayList<ILocatorChangeListener> mutableListenerList,
            final IJarLocator provider,
            final ContentTypeResolver contentTypeResolver)
    {
        super(id, displayName, noResultValue, mutableListenerList);
        _provider = provider;
        _contentTypeResolver = contentTypeResolver;
    }

    /**
     * @param noResultValue
     * @param mutableListenerList
     * @param provider
     * @param contentTypeResolver
     */
    public JarBasedJSFResourceLocator(
            final List<IJSFResourceFragment> noResultValue,
            final CopyOnWriteArrayList<ILocatorChangeListener> mutableListenerList,
            final IJarLocator provider,
            final ContentTypeResolver contentTypeResolver)
    {
        this(
                "", "", noResultValue, mutableListenerList, provider, contentTypeResolver); //$NON-NLS-1$//$NON-NLS-2$
    }

    @Override
    public void start(final IProject initialContext)
    {
        _provider.start(initialContext);
        super.start(initialContext);
    }

    @Override
    public void stop()
    {
        _provider.stop();
        super.stop();
    }

    @Override
    protected List<IJSFResourceFragment> doLocate(final IProject project)
    {
        final List<IJSFResourceFragment> resourcesFound = new ArrayList<IJSFResourceFragment>();
        final Collection<? extends ClasspathJarFile> jars = _provider
                .getJars(project);
        for (final ClasspathJarFile classpathJarFile : jars)
        {
            final JarFile jarFile = classpathJarFile.getJarFile();
            if (jarFile != null)
            {
                resourcesFound.addAll(processJar(jarFile));
            }
        }
        return resourcesFound;
    }

    /**
     * @param entry
     * @param defaultDtdStream
     * @throws Exception
     */
    private List<JSFResource> processJar(final JarFile jarFile)
    {
        final List<JSFResource> tagLibsFound = new ArrayList<JSFResource>();
        try
        {
            if (jarFile != null)
            {
                final JarEntryMatchingAcceptor acceptor = new JarEntryMatchingAcceptor();
                final VisitorMatcher<JarFile, JarEntry, String> matcher = new VisitorMatcher<JarFile, JarEntry, String>(
                        "", "", acceptor, Collections.singletonList(_resourceFinder)); //$NON-NLS-1$//$NON-NLS-2$
                final Collection<? extends JarEntry> matchingEntries = matcher
                        .find(jarFile);
                for (final JarEntry jarEntry : matchingEntries)
                {
                    try
                    {
                        final Matcher patternMatcher = _resourcePathPattern
                                .matcher(jarEntry.getName());
                        if (patternMatcher.matches())
                        {
                            final String group = patternMatcher.group(1);
                            if (group != null && group.trim().length() > 0)
                            {
                                final ResourceIdentifier libRes = new ResourceIdentifierFactory()
                                        .createLibraryResource(group);
                                final URL jarUrl = JarUtilities.INSTANCE
                                        .createJarUrl(jarFile);
                                tagLibsFound.add(new JarBasedJSFResource(
                                        libRes, jarUrl, _contentTypeResolver));
                            }
                        }
                    } catch (final Exception e)
                    {
                        JSFCorePlugin.log(
                                "Error initializing facelet registry entry", //$NON-NLS-1$
                                e);
                    }
                }
            }
        } catch (final Exception e)
        {
            JSFCorePlugin.log(e,
                    "While locating jar based facelet tag libraries"); //$NON-NLS-1$
        } finally
        {
            if (jarFile != null)
            {
                try
                {
                    jarFile.close();
                } catch (final IOException ioe)
                {
                    JSFCorePlugin.log("Error closing jar file", ioe); //$NON-NLS-1$
                }
            }
        }
        return tagLibsFound;
    }
}
