/*
 * 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.
 */

package freemarker.cache;

import java.io.IOException;
import java.io.Reader;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * A {@link TemplateLoader} that uses a set of other loaders to load the templates. On every request, loaders are
 * queried in the order of their appearance in the array of loaders provided to the constructor. However, if a request
 * for some template name was already satisfied in the past by one of the loaders, that Loader is queried first (a soft
 * affinity).
 * 
 * <p>
 * This class is <em>not</em> thread-safe. If it's accessed from multiple threads concurrently, proper synchronization
 * must be provided by the callers. Note that {@link TemplateCache}, the natural user of this class, provides the
 * necessary synchronizations when it uses this class, so then you don't have to worry this.
 */
public class MultiTemplateLoader implements StatefulTemplateLoader {

    private final TemplateLoader[] loaders;
    private final Map lastLoaderForName = Collections.synchronizedMap(new HashMap());

    /**
     * Creates a new multi template Loader that will use the specified loaders.
     * 
     * @param loaders
     *            the loaders that are used to load templates.
     */
    public MultiTemplateLoader(TemplateLoader[] loaders) {
        this.loaders = loaders.clone();
    }

    public Object findTemplateSource(String name)
            throws IOException {
        // Use soft affinity - give the loader that last found this
        // resource a chance to find it again first.
        TemplateLoader lastLoader = (TemplateLoader) lastLoaderForName.get(name);
        if (lastLoader != null) {
            Object source = lastLoader.findTemplateSource(name);
            if (source != null) {
                return new MultiSource(source, lastLoader);
            }
        }

        // If there is no affine loader, or it could not find the resource
        // again, try all loaders in order of appearance. If any manages
        // to find the resource, then associate it as the new affine loader
        // for this resource.
        for (int i = 0; i < loaders.length; ++i) {
            TemplateLoader loader = loaders[i];
            Object source = loader.findTemplateSource(name);
            if (source != null) {
                lastLoaderForName.put(name, loader);
                return new MultiSource(source, loader);
            }
        }

        lastLoaderForName.remove(name);
        // Resource not found
        return null;
    }

    private Object modifyForIcI(Object source) {
        // TODO Auto-generated method stub
        return null;
    }

    public long getLastModified(Object templateSource) {
        return ((MultiSource) templateSource).getLastModified();
    }

    public Reader getReader(Object templateSource, String encoding)
            throws IOException {
        return ((MultiSource) templateSource).getReader(encoding);
    }

    public void closeTemplateSource(Object templateSource)
            throws IOException {
        ((MultiSource) templateSource).close();
    }

    public void resetState() {
        lastLoaderForName.clear();
        for (int i = 0; i < loaders.length; i++) {
            TemplateLoader loader = loaders[i];
            if (loader instanceof StatefulTemplateLoader) {
                ((StatefulTemplateLoader) loader).resetState();
            }
        }
    }

    /**
     * Represents a template source bound to a specific template loader. It serves as the complete template source
     * descriptor used by the MultiTemplateLoader class.
     */
    static final class MultiSource {

        private final Object source;
        private final TemplateLoader loader;

        MultiSource(Object source, TemplateLoader loader) {
            this.source = source;
            this.loader = loader;
        }

        long getLastModified() {
            return loader.getLastModified(source);
        }

        Reader getReader(String encoding)
                throws IOException {
            return loader.getReader(source, encoding);
        }

        void close()
                throws IOException {
            loader.closeTemplateSource(source);
        }

        Object getWrappedSource() {
            return source;
        }

        @Override
        public boolean equals(Object o) {
            if (o instanceof MultiSource) {
                MultiSource m = (MultiSource) o;
                return m.loader.equals(loader) && m.source.equals(source);
            }
            return false;
        }

        @Override
        public int hashCode() {
            return loader.hashCode() + 31 * source.hashCode();
        }

        @Override
        public String toString() {
            return source.toString();
        }
    }

    /**
     * Show class name and some details that are useful in template-not-found errors.
     * 
     * @since 2.3.21
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("MultiTemplateLoader(");
        for (int i = 0; i < loaders.length; i++) {
            if (i != 0) {
                sb.append(", ");
            }
            sb.append("loader").append(i + 1).append(" = ").append(loaders[i]);
        }
        sb.append(")");
        return sb.toString();
    }

    /**
     * Returns the number of {@link TemplateLoader}-s directly inside this {@link TemplateLoader}.
     * 
     * @since 2.3.23
     */
    public int getTemplateLoaderCount() {
        return loaders.length;
    }

    /**
     * Returns the {@link TemplateLoader} at the given index.
     * 
     * @param index
     *            Must be below {@link #getTemplateLoaderCount()}.
     */
    public TemplateLoader getTemplateLoader(int index) {
        return loaders[index];
    }

}
