/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.fop.apps.io;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.xmlgraphics.io.Resource;
import org.apache.xmlgraphics.io.ResourceResolver;
import org.apache.xmlgraphics.io.TempResourceResolver;
import org.apache.xmlgraphics.io.TempResourceURIGenerator;

/**
 * A factory class for {@link ResourceResolver}s.
 */
public final class ResourceResolverFactory {

    private ResourceResolverFactory() {
    }

    /**
     * Returns the default resource resolver, this is most basic resolver which can be used when
     * no there are no I/O or file access restrictions.
     *
     * @return the default resource resolver
     */
    public static ResourceResolver createDefaultResourceResolver() {
        return DefaultResourceResolver.INSTANCE;
    }

    /**
     * A helper merthod that creates an internal resource resolver using the default resover:
     * {@link ResourceResolverFactory#createDefaultResourceResolver()}.
     *
     * @param baseURI the base URI from which to resolve URIs
     * @return the default internal resource resolver
     */
    public static InternalResourceResolver createDefaultInternalResourceResolver(URI baseURI) {
        return new InternalResourceResolver(baseURI, createDefaultResourceResolver());
    }

    /**
     * Creates an interal resource resolver given a base URI and a resource resolver.
     *
     * @param baseURI the base URI from which to resolve URIs
     * @param resolver the resource resolver
     * @return the internal resource resolver
     */
    public static InternalResourceResolver createInternalResourceResolver(URI baseURI,
            ResourceResolver resolver) {
        return new InternalResourceResolver(baseURI, resolver);
    }

    /**
     * Creates a temporary-resource-scheme aware resource resolver. Temporary resource URIs are
     * created by {@link TempResourceURIGenerator}.
     *
     * @param tempResourceResolver the temporary-resource-scheme resolver to use
     * @param defaultResourceResolver the default resource resolver to use
     * @return the ressource resolver
     */
    public static ResourceResolver createTempAwareResourceResolver(
            TempResourceResolver tempResourceResolver,
            ResourceResolver defaultResourceResolver) {
        return new TempAwareResourceResolver(tempResourceResolver, defaultResourceResolver);
    }

    /**
     * This creates the builder class for binding URI schemes to implementations of
     * {@link ResourceResolver}. This allows users to define their own URI schemes such that they
     * have finer control over the acquisition of resources.
     *
     * @param defaultResolver the default resource resolver that should be used in the event that
     * none of the other registered resolvers match the scheme
     * @return the scheme aware {@link ResourceResolver} builder
     */
    public static SchemeAwareResourceResolverBuilder createSchemeAwareResourceResolverBuilder(
            ResourceResolver defaultResolver) {
        return new SchemeAwareResourceResolverBuilderImpl(defaultResolver);
    }

    private static final class DefaultResourceResolver implements ResourceResolver {

        private static final ResourceResolver INSTANCE = new DefaultResourceResolver();

        private final TempAwareResourceResolver delegate;

        private DefaultResourceResolver() {
            delegate = new TempAwareResourceResolver(new DefaultTempResourceResolver(),
                    new NormalResourceResolver());
        }

        /** {@inheritDoc} */
        public Resource getResource(URI uri) throws IOException {
            return delegate.getResource(uri);
        }

        /** {@inheritDoc} */
        public OutputStream getOutputStream(URI uri) throws IOException {
            return delegate.getOutputStream(uri);
        }

    }

    private static final class TempAwareResourceResolver implements ResourceResolver {

        private final TempResourceResolver tempResourceResolver;

        private final ResourceResolver defaultResourceResolver;

        public TempAwareResourceResolver(TempResourceResolver tempResourceHandler,
                ResourceResolver defaultResourceResolver) {
            this.tempResourceResolver = tempResourceHandler;
            this.defaultResourceResolver = defaultResourceResolver;
        }

        private static boolean isTempURI(URI uri) {
            return TempResourceURIGenerator.isTempURI(uri);
        }

        /** {@inheritDoc} */
        public Resource getResource(URI uri) throws IOException {
            if (isTempURI(uri)) {
                return tempResourceResolver.getResource(uri.getPath());
            } else {
                return defaultResourceResolver.getResource(uri);
            }
        }

        /** {@inheritDoc} */
        public OutputStream getOutputStream(URI uri) throws IOException {
            if (isTempURI(uri)) {
                return tempResourceResolver.getOutputStream(uri.getPath());
            } else {
                return defaultResourceResolver.getOutputStream(uri);
            }
        }
    }

    private static class DefaultTempResourceResolver implements TempResourceResolver {

        private final ConcurrentHashMap<String, File> tempFiles = new ConcurrentHashMap<String, File>();

        private File getTempFile(String uri) throws IllegalStateException {
            File tempFile = tempFiles.remove(uri);
            if (tempFile == null) {
                throw new IllegalStateException(uri + " was never created or has been deleted");
            }
            return tempFile;
        }

        private File createTempFile(String path) throws IOException {
            File tempFile = File.createTempFile(path, ".fop.tmp");
            File oldFile = tempFiles.put(path, tempFile);
            if (oldFile != null) {
                String errorMsg = oldFile.getAbsolutePath() + " has been already created for " + path;
                boolean newTempDeleted = tempFile.delete();
                if (!newTempDeleted) {
                    errorMsg += ". " + tempFile.getAbsolutePath() + " was not deleted.";
                }
                throw new IOException(errorMsg);
            }
            return tempFile;
        }

        /** {@inheritDoc} */
        public Resource getResource(String id) throws IOException {
            return new Resource(new FileDeletingInputStream(getTempFile(id)));
        }

        /** {@inheritDoc} */
        public OutputStream getOutputStream(String id) throws IOException {
            return new FileOutputStream(createTempFile(id));
        }
    }

    private static class FileDeletingInputStream extends FilterInputStream {

        private final File file;

        protected FileDeletingInputStream(File file) throws MalformedURLException, IOException {
            super(file.toURI().toURL().openStream());
            this.file = file;
        }

        @Override
        public void close() throws IOException {
            try {
                super.close();
            } finally {
                file.delete();
            }
        }
    }

    private static class NormalResourceResolver implements ResourceResolver {
        public Resource getResource(URI uri) throws IOException {
            return new Resource(uri.toURL().openStream());
        }

        public OutputStream getOutputStream(URI uri) throws IOException {
            return new FileOutputStream(new File(uri));
        }
    }

    private static final class SchemeAwareResourceResolver implements ResourceResolver {

        private final Map<String, ResourceResolver> schemeHandlingResourceResolvers;

        private final ResourceResolver defaultResolver;

        private SchemeAwareResourceResolver(
                Map<String, ResourceResolver> schemEHandlingResourceResolvers,
                ResourceResolver defaultResolver) {
            this.schemeHandlingResourceResolvers = schemEHandlingResourceResolvers;
            this.defaultResolver = defaultResolver;
        }

        private ResourceResolver getResourceResolverForScheme(URI uri) {
            String scheme = uri.getScheme();
            if (schemeHandlingResourceResolvers.containsKey(scheme)) {
                return schemeHandlingResourceResolvers.get(scheme);
            } else {
                return defaultResolver;
            }
        }

        /** {@inheritDoc} */
        public Resource getResource(URI uri) throws IOException {
            return getResourceResolverForScheme(uri).getResource(uri);
        }

        /** {@inheritDoc} */
        public OutputStream getOutputStream(URI uri) throws IOException {
            return getResourceResolverForScheme(uri).getOutputStream(uri);
        }
    }

    /**
     * Implementations of this interface will be builders for {@link ResourceResolver}, they bind
     * URI schemes to their respective resolver. This gives users more control over the mechanisms
     * by which URIs are resolved.
     * <p>
     * Here is an example of how this could be used:
     * </p>
     * <p><code>
     * SchemeAwareResourceResolverBuilder builder
     *      = ResourceResolverFactory.createSchemeAwareResourceResolverBuilder(defaultResolver);
     * builder.registerResourceResolverForScheme("test", testResolver);
     * builder.registerResourceResolverForScheme("anotherTest", test2Resolver);
     * ResourceResolver resolver = builder.build();
     * </code></p>
     * This will result in all URIs for the form "test:///..." will be resolved using the
     * <code>testResolver</code> object; URIs of the form "anotherTest:///..." will be resolved
     * using <code>test2Resolver</code>; all other URIs will be resolved from the defaultResolver.
     */
    public interface SchemeAwareResourceResolverBuilder {

        /**
         * Register a scheme with its respective {@link ResourceResolver}. This resolver will be
         * used as the only resolver for the specified scheme.
         *
         * @param scheme the scheme to be used with the given resolver
         * @param resourceResolver the resource resolver
         */
        void registerResourceResolverForScheme(String scheme, ResourceResolver resourceResolver);

        /**
         * Builds a {@link ResourceResolver} that will delegate to the respective resource resolver
         * when a registered URI scheme is given
         *
         * @return a resolver that delegates to the appropriate scheme resolver
         */
        ResourceResolver build();
    }

    private static final class CompletedSchemeAwareResourceResolverBuilder
            implements SchemeAwareResourceResolverBuilder {

        private static final SchemeAwareResourceResolverBuilder INSTANCE
                = new CompletedSchemeAwareResourceResolverBuilder();

        /** {@inheritDoc} */
        public ResourceResolver build() {
            throw new IllegalStateException("Resource resolver already built");
        }

        /** {@inheritDoc} */
        public void registerResourceResolverForScheme(String scheme,
                ResourceResolver resourceResolver) {
            throw new IllegalStateException("Resource resolver already built");
        }
    }

    private static final class ActiveSchemeAwareResourceResolverBuilder
            implements SchemeAwareResourceResolverBuilder {

        private final Map<String, ResourceResolver> schemeHandlingResourceResolvers
                = new HashMap<String, ResourceResolver>();

        private final ResourceResolver defaultResolver;

        private ActiveSchemeAwareResourceResolverBuilder(ResourceResolver defaultResolver) {
            this.defaultResolver = defaultResolver;
        }

        /** {@inheritDoc} */
        public void registerResourceResolverForScheme(String scheme,
                ResourceResolver resourceResolver) {
            schemeHandlingResourceResolvers.put(scheme, resourceResolver);
        }

        /** {@inheritDoc} */
        public ResourceResolver build() {
            return new SchemeAwareResourceResolver(
                    Collections.unmodifiableMap(schemeHandlingResourceResolvers), defaultResolver);
        }

    }

    private static final class SchemeAwareResourceResolverBuilderImpl
            implements SchemeAwareResourceResolverBuilder {

        private SchemeAwareResourceResolverBuilder delegate;

        private SchemeAwareResourceResolverBuilderImpl(ResourceResolver defaultResolver) {
            this.delegate = new ActiveSchemeAwareResourceResolverBuilder(defaultResolver);
        }

        /** {@inheritDoc} */
        public void registerResourceResolverForScheme(String scheme,
                ResourceResolver resourceResolver) {
            delegate.registerResourceResolverForScheme(scheme, resourceResolver);
        }

        /** {@inheritDoc} */
        public ResourceResolver build() {
            ResourceResolver resourceResolver = delegate.build();
            delegate = CompletedSchemeAwareResourceResolverBuilder.INSTANCE;
            return resourceResolver;
        }
    }
}
