/*
 * 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.util.Locale;

import freemarker.template.Configuration;
import freemarker.template.Template;

/**
 * Finds the {@link TemplateLoader}-level (storage-level) template source for the template name with which the template
 * was requested (as in {@link Configuration#getTemplate(String)}). This usually means trying various
 * {@link TemplateLoader}-level template names (so called source names; see also {@link Template#getSourceName()}) that
 * were deduced from the requested name. Trying a name usually means calling
 * {@link TemplateLookupContext#lookupWithAcquisitionStrategy(String)} with it and checking the value of
 * {@link TemplateLookupResult#isPositive()}.
 * 
 * <p>
 * Before you write your own lookup strategy, know that:
 * <ul>
 * <li>A template lookup strategy meant to operate solely with template names, not with {@link TemplateLoader}-s
 * directly. Basically, it's a mapping between the template names that templates and API-s like
 * {@link Configuration#getTemplate(String)} see, and those that the underlying {@link TemplateLoader} sees.
 * <li>A template lookup strategy doesn't influence the template's name ({@link Template#getName()}), which is the
 * normalized form of the template name as it was requested (with {@link Configuration#getTemplate(String)}, etc.). It
 * only influences the so called source name of the template ({@link Template#getSourceName()}). The template's name is
 * used as the basis for resolving relative inclusions/imports in the template. The source name is pretty much only used
 * in error messages as error location, and of course, to actually load the template "file".
 * <li>Understand the impact of the last point if your template lookup strategy fiddles not only with the file name part
 * of the template name, but also with the directory part. For example, one may want to map "foo.ftl" to "en/foo.ftl",
 * "fr/foo.ftl", etc. That's legal, but the result is kind of like if you had several root directories ("en/", "fr/",
 * etc.) that are layered over each other to form a single merged directory. (This is what's desirable in typical
 * applications, yet it can be confusing.)
 * </ul>
 * 
 * @see Configuration#setTemplateLookupStrategy(TemplateLookupStrategy)
 * 
 * @since 2.3.22
 */
public abstract class TemplateLookupStrategy {

    /**
     * <p>
     * The default lookup strategy of FreeMarker.
     * 
     * <p>
     * Through an example: Assuming localized lookup is enabled and that a template is requested for the name
     * {@code example.ftl} and {@code Locale("es", "ES", "Traditional_WIN")}, it will try the following template names,
     * in this order: {@code "foo_en_AU_Traditional_WIN.ftl"}, {@code "foo_en_AU_Traditional.ftl"},
     * {@code "foo_en_AU.ftl"}, {@code "foo_en.ftl"}, {@code "foo.ftl"}. It stops at the first variation where it finds
     * a template. (If the template name contains "*" steps, finding the template for the attempted localized variation
     * happens with the template acquisition mechanism.) If localized lookup is disabled, it won't try to add any locale
     * strings, so it just looks for {@code "foo.ftl"}.
     * 
     * <p>
     * The generation of the localized name variation with the default lookup strategy, happens like this: It removes
     * the file extension (the part starting with the <em>last</em> dot), then appends {@link Locale#toString()} after
     * it, and puts back the extension. Then it starts to remove the parts from the end of the locale, considering
     * {@code "_"} as the separator between the parts. It won't remove parts that are not part of the locale string
     * (like if the requested template name is {@code foo_bar.ftl}, it won't remove the {@code "_bar"}).
     */
    public static final TemplateLookupStrategy DEFAULT_2_3_0 = new Default020300();
    
    /**
     * Finds the template source that matches the template name, locale (if not {@code null}) and other parameters
     * specified in the {@link TemplateLookupContext}. See also the class-level {@link TemplateLookupStrategy}
     * documentation to understand lookup strategies more.
     * 
     * @param ctx
     *            Contains the parameters for which the matching template need to be found, and operations that
     *            are needed to implement the strategy. Some of the important input parameters are:
     *            {@link TemplateLookupContext#getTemplateName()}, {@link TemplateLookupContext#getTemplateLocale()}.
     *            The most important operations are {@link TemplateLookupContext#lookupWithAcquisitionStrategy(String)}
     *            and {@link TemplateLookupContext#createNegativeLookupResult()}. (Note that you deliberately can't
     *            use {@link TemplateLoader}-s directly to implement lookup.)
     * 
     * @return Usually the return value of {@link TemplateLookupContext#lookupWithAcquisitionStrategy(String)}, or
     *         {@code TemplateLookupContext#createNegativeLookupResult()} if no matching template exists. Can't be
     *         {@code null}.
     */
    public abstract TemplateLookupResult lookup(TemplateLookupContext ctx) throws IOException;
    
    private static class Default020300 extends TemplateLookupStrategy {
        
        @Override
        public TemplateLookupResult lookup(TemplateLookupContext ctx) throws IOException {
            return ctx.lookupWithLocalizedThenAcquisitionStrategy(ctx.getTemplateName(), ctx.getTemplateLocale());
        }
        
        @Override
        public String toString() {
            return "TemplateLookupStrategy.DEFAULT_2_3_0";
        }
        
    }
    
}
