/*
 * 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.net.URL;

import freemarker.template.utility.NullArgumentException;
import freemarker.template.utility.StringUtil;

/**
 * A {@link TemplateLoader} that can load templates from the "classpath". Naturally, it can load from jar files, or from
 * anywhere where Java can load classes from. Internally, it uses {@link Class#getResource(String)} or
 * {@link ClassLoader#getResource(String)} to load templates.
 */
public class ClassTemplateLoader extends URLTemplateLoader {
    
    private final Class resourceLoaderClass;
    private final ClassLoader classLoader;
    private final String basePackagePath;

    /**
     * Creates a template loader that will use the {@link Class#getResource(String)} method of its own class to load the
     * resources, and {@code "/"} as base package path. This means that that template paths will be resolved relatively
     * the root package of the class hierarchy, so you hardly ever should use this constructor, rather do something like
     * this:<br>
     * {@link #ClassTemplateLoader(Class, String) new ClassTemplateLoader(com.example.myapplication.SomeClass.class,
     * "templates")}
     *
     * <p>
     * If you extend this class, then the extending class will be used to load the resources.
     *
     * @deprecated It's a confusing constructor, and seldom useful; use {@link #ClassTemplateLoader(Class, String)}
     *             instead.
     */
    @Deprecated
    public ClassTemplateLoader() {
        this(null, true, null, "/");
    }

    /**
     * Creates a template loader that will use the {@link Class#getResource(String)} method of the specified class to
     * load the resources, and {@code ""} as base package path. This means that template paths will be resolved
     * relatively to the class location, that is, relatively to the directory (package) of the class.
     *
     * @param resourceLoaderClass
     *            the class whose {@link Class#getResource(String)} will be used to load the templates.
     *
     * @deprecated It's confusing that the base path is {@code ""}; use {@link #ClassTemplateLoader(Class, String)}
     *             instead.
     */
    @Deprecated
    public ClassTemplateLoader(Class resourceLoaderClass) {
        this(resourceLoaderClass, "");
    }

    /**
     * Creates a template loader that will use the {@link Class#getResource(String)} method of the specified class to
     * load the resources, and the specified base package path (absolute or relative).
     *
     * <p>
     * Examples:
     * <ul>
     * <li>Relative base path (will load from the {@code com.example.myapplication.templates} package):<br>
     * {@code new ClassTemplateLoader(com.example.myapplication.SomeClass.class, "templates")}
     * <li>Absolute base path:<br>
     * {@code new ClassTemplateLoader(somepackage.SomeClass.class, "/com/example/myapplication/templates")}
     * </ul>
     *
     * @param resourceLoaderClass
     *            The class whose {@link Class#getResource(String)} method will be used to load the templates. Be sure
     *            that you chose a class whose defining class-loader sees the templates. This parameter can't be
     *            {@code null}.
     * @param basePackagePath
     *            The package that contains the templates, in path ({@code /}-separated) format. If it doesn't start
     *            with a {@code /} then it's relative to the path (package) of the {@code resourceLoaderClass} class. If
     *            it starts with {@code /} then it's relative to the root of the package hierarchy. Note that path
     *            components should be separated by forward slashes independently of the separator character used by the
     *            underlying operating system. This parameter can't be {@code null}.
     * 
     * @see #ClassTemplateLoader(ClassLoader, String)
     */
    public ClassTemplateLoader(Class resourceLoaderClass, String basePackagePath) {
        this(resourceLoaderClass, false, null, basePackagePath);
    }

    /**
     * Similar to {@link #ClassTemplateLoader(Class, String)}, but instead of {@link Class#getResource(String)} it uses
     * {@link ClassLoader#getResource(String)}. Because a {@link ClassLoader} isn't bound to any Java package, it
     * doesn't mater if the {@code basePackagePath} starts with {@code /} or not, it will be always relative to the root
     * of the package hierarchy
     * 
     * @since 2.3.22
     */
    public ClassTemplateLoader(ClassLoader classLoader, String basePackagePath) {
        this(null, true, classLoader, basePackagePath);
    }

    private ClassTemplateLoader(Class resourceLoaderClass, boolean allowNullBaseClass, ClassLoader classLoader,
            String basePackagePath) {
        if (!allowNullBaseClass) {
            NullArgumentException.check("resourceLoaderClass", resourceLoaderClass);
        }
        NullArgumentException.check("basePackagePath", basePackagePath);

        // Either set a non-null resourceLoaderClass or a non-null classLoader, not both:
        this.resourceLoaderClass = classLoader == null ? (resourceLoaderClass == null ? this.getClass()
                : resourceLoaderClass) : null;
        if (this.resourceLoaderClass == null && classLoader == null) {
            throw new NullArgumentException("classLoader");
        }
        this.classLoader = classLoader;

        String canonBasePackagePath = canonicalizePrefix(basePackagePath);
        if (this.classLoader != null && canonBasePackagePath.startsWith("/")) {
            canonBasePackagePath = canonBasePackagePath.substring(1);
        }
        this.basePackagePath = canonBasePackagePath;
    }

    @Override
    protected URL getURL(String name) {
        String fullPath = basePackagePath + name;

        // Block java.net.URLClassLoader exploits:
        if (basePackagePath.equals("/") && !isSchemeless(fullPath)) {
            return null;
        }

        return resourceLoaderClass != null ? resourceLoaderClass.getResource(fullPath) : classLoader
                .getResource(fullPath);
    }

    private static boolean isSchemeless(String fullPath) {
        int i = 0;
        int ln = fullPath.length();

        // Skip a single initial /, as things like "/file:/..." might work:
        if (i < ln && fullPath.charAt(i) == '/') i++;

        // Check if there's no ":" earlier than a '/', as the URLClassLoader
        // could interpret that as an URL scheme:
        while (i < ln) {
            char c = fullPath.charAt(i);
            if (c == '/') return true;
            if (c == ':') return false;
            i++;
        }
        return true;
    }

    /**
     * Show class name and some details that are useful in template-not-found errors.
     * 
     * @since 2.3.21
     */
    @Override
    public String toString() {
        return TemplateLoaderUtils.getClassNameForToString(this) + "("
                + (resourceLoaderClass != null
                        ? "resourceLoaderClass=" + resourceLoaderClass.getName()
                        : "classLoader=" + StringUtil.jQuote(classLoader))
                + ", basePackagePath"
                + "="
                + StringUtil.jQuote(basePackagePath)
                + (resourceLoaderClass != null
                        ? (basePackagePath.startsWith("/") ? "" : " /* relatively to resourceLoaderClass pkg */")
                        : ""
                )
                + ")";
    }

    /**
     * See the similar parameter of {@link #ClassTemplateLoader(Class, String)}; {@code null} when other mechanism is
     * used to load the resources.
     * 
     * @since 2.3.22
     */
    public Class getResourceLoaderClass() {
        return resourceLoaderClass;
    }

    /**
     * See the similar parameter of {@link #ClassTemplateLoader(ClassLoader, String)}; {@code null} when other mechanism
     * is used to load the resources.
     * 
     * @since 2.3.22
     */
    public ClassLoader getClassLoader() {
        return classLoader;
    }

    /**
     * See the similar parameter of {@link #ClassTemplateLoader(ClassLoader, String)}; note that this is a normalized
     * version of what was actually passed to the constructor.
     * 
     * @since 2.3.22
     */
    public String getBasePackagePath() {
        return basePackagePath;
    }

}