/*
 * 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.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * 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-schema aware resource resolver. Temporary resource URIs are
     * created by {@link TempResourceURIGenerator}.
     *
     * @param tempResourceResolver the temporary-resource-schema 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 schemas to implementations of
     * {@link ResourceResolver}. This allows users to define their own URI schemas 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 schema
     * @return the schema aware {@link ResourceResolver} builder
     */
    public static SchemaAwareResourceResolverBuilder createSchemaAwareResourceResolverBuilder(
            ResourceResolver defaultResolver) {
        return new SchemaAwareResourceResolverBuilderImpl(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 static File getTempFile(String path) throws IOException {
            File file = new File(System.getProperty("java.io.tmpdir"), path);
            file.deleteOnExit();
            return file;
        }

        /** {@inheritDoc} */
        public Resource getResource(String id) throws IOException {
            return new Resource(getTempFile(id).toURI().toURL().openStream());
        }

        /** {@inheritDoc} */
        public OutputStream getOutputStream(String id) throws IOException {
            File file = getTempFile(id);
            if (file.createNewFile()) {
                return new FileOutputStream(file);
            } else {
                throw new IOException("Filed to create temporary file: " + id);
            }
        }
    }

    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 SchemaAwareResourceResolver implements ResourceResolver {

        private final Map<String, ResourceResolver> schemaHandlingResourceResolvers;

        private final ResourceResolver defaultResolver;

        private SchemaAwareResourceResolver(
                Map<String, ResourceResolver> schemaHandlingResourceResolvers,
                ResourceResolver defaultResolver) {
            this.schemaHandlingResourceResolvers = schemaHandlingResourceResolvers;
            this.defaultResolver = defaultResolver;
        }

        private ResourceResolver getResourceResolverForSchema(URI uri) {
            String schema = uri.getScheme();
            if (schemaHandlingResourceResolvers.containsKey(schema)) {
                return schemaHandlingResourceResolvers.get(schema);
            } else {
                return defaultResolver;
            }
        }

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

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

    /**
     * Implementations of this interface will be builders for {@link ResourceResolver}, they bind
     * URI schemas 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>
     * SchemaAwareResourceResolverBuilder builder
     *      = ResourceResolverFactory.createSchemaAwareResourceResolverBuilder(defaultResolver);
     * builder.registerResourceResolverForSchema("test", testResolver);
     * builder.registerResourceResolverForSchema("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 SchemaAwareResourceResolverBuilder {

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

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

    private static final class CompletedSchemaAwareResourceResolverBuilder
            implements SchemaAwareResourceResolverBuilder {

        private static final SchemaAwareResourceResolverBuilder INSTANCE
                = new CompletedSchemaAwareResourceResolverBuilder();

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

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

    private static final class ActiveSchemaAwareResourceResolverBuilder
            implements SchemaAwareResourceResolverBuilder {

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

        private final ResourceResolver defaultResolver;

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

        /** {@inheritDoc} */
        public void registerResourceResolverForSchema(String schema,
                ResourceResolver resourceResolver) {
            schemaHandlingResourceResolvers.put(schema, resourceResolver);
        }

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

    }

    private static final class SchemaAwareResourceResolverBuilderImpl
            implements SchemaAwareResourceResolverBuilder {

        private SchemaAwareResourceResolverBuilder delegate;

        private SchemaAwareResourceResolverBuilderImpl(ResourceResolver defaultResolver) {
            this.delegate = new ActiveSchemaAwareResourceResolverBuilder(defaultResolver);
        }

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

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

}
