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

import java.io.IOException;

import org.junit.Before;
import org.junit.Test;

import freemarker.cache.StringTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.Version;
import freemarker.template.utility.StringUtil;
import freemarker.test.TemplateTest;

public class TemplateNameSpecialVariablesTest extends TemplateTest {
    
    private static final Version[] BREAK_POINT_VERSIONS = new Version[] {
            Configuration.VERSION_2_3_0, Configuration.VERSION_2_3_22, Configuration.VERSION_2_3_23 };

    private static TemplateLoader createTemplateLoader(String specVar) {
        StringTemplateLoader tl = new StringTemplateLoader();
        tl.putTemplate("main.ftl",
                "In main: ${" + specVar + "}\n"
                + "<#import 'imp.ftl' as i>"
                + "In imp: ${inImp}\n"
                + "In main: ${" + specVar + "}\n"
                + "<@i.impM>${" + specVar + "}</@>\n"
                + "<@i.impM2 />\n"
                + "In main: ${" + specVar + "}\n"
                + "<#include 'inc.ftl'>"
                + "In main: ${" + specVar + "}\n"
                + "<@incM>${" + specVar + "}</@>\n"
                + "<@incM2 />\n"
                + "In main: ${" + specVar + "}\n"
                );
        tl.putTemplate("imp.ftl",
                "<#global inImp = " + specVar + ">"
                + "<#macro impM>"
                    + "${" + specVar + "}\n"
                    + "{<#nested>}"
                + "</#macro>"
                + "<#macro impM2>"
                    + "In imp call imp:\n"
                    + "<@impM>${" + specVar + "}</@>\n"
                    + "After: ${" + specVar + "}"
                + "</#macro>"
                );
        tl.putTemplate("inc.ftl",
                "In inc: ${" + specVar + "}\n"
                + "In inc call imp:\n"
                + "<@i.impM>${" + specVar + "}</@>\n"
                + "<#macro incM>"
                    + "${" + specVar + "}\n"
                    + "{<#nested>}"
                + "</#macro>"
                + "<#macro incM2>"
                    + "In inc call imp:\n"
                    + "<@i.impM>${" + specVar + "}</@>"
                + "</#macro>"
                );
        return tl;
    }

    private static final String PRINT_ALL_FTL
            = "t=${.templateName}, ct=${.currentTemplateName!'-'}, mt=${.mainTemplateName!'-'}";
    
    @Test
    public void testTemplateName230() throws IOException, TemplateException {
        getConfiguration().setTemplateLoader(createTemplateLoader(".templateName"));
        getConfiguration().setIncompatibleImprovements(Configuration.VERSION_2_3_0);
        assertMainFtlOutput(false);
    }
    
    /** This IcI version was buggy. */
    @Test
    public void testTemplateName2322() throws IOException, TemplateException {
        getConfiguration().setTemplateLoader(createTemplateLoader(".templateName"));
        getConfiguration().setIncompatibleImprovements(Configuration.VERSION_2_3_22);
        assertMainFtlOutput(true);
    }
    
    @Test
    public void testTemplateName2323() throws IOException, TemplateException {
        getConfiguration().setTemplateLoader(createTemplateLoader(".templateName"));
        getConfiguration().setIncompatibleImprovements(Configuration.VERSION_2_3_23);
        assertMainFtlOutput(false);
    }

    @Test
    public void testMainTemplateName() throws IOException, TemplateException {
        getConfiguration().setTemplateLoader(createTemplateLoader(".mainTemplateName"));
        for (Version ici : BREAK_POINT_VERSIONS) {
            getConfiguration().setIncompatibleImprovements(ici);
            assertMainFtlOutput(true);
        }
    }

    @Test
    public void testCurrentTemplateName() throws IOException, TemplateException {
        getConfiguration().setTemplateLoader(createTemplateLoader(".currentTemplateName"));
        for (Version ici : BREAK_POINT_VERSIONS) {
            getConfiguration().setIncompatibleImprovements(ici);
            assertOutputForNamed("main.ftl",
                    "In main: main.ftl\n"
                    + "In imp: imp.ftl\n"
                    + "In main: main.ftl\n"
                    + "imp.ftl\n"
                    + "{main.ftl}\n"
                    + "In imp call imp:\n"
                    + "imp.ftl\n"
                    + "{imp.ftl}\n"
                    + "After: imp.ftl\n"
                    + "In main: main.ftl\n"
                    + "In inc: inc.ftl\n"
                    + "In inc call imp:\n"
                    + "imp.ftl\n"
                    + "{inc.ftl}\n"
                    + "In main: main.ftl\n"
                    + "inc.ftl\n"
                    + "{main.ftl}\n"
                    + "In inc call imp:\n"
                    + "imp.ftl\n"
                    + "{inc.ftl}\n"
                    + "In main: main.ftl\n");
        }
    }
    
    protected void assertMainFtlOutput(boolean allMain) throws IOException, TemplateException {
        String expected
                = "In main: main.ftl\n"
                + "In imp: imp.ftl\n"
                + "In main: main.ftl\n"
                + "main.ftl\n"
                + "{main.ftl}\n"
                + "In imp call imp:\n"
                + "main.ftl\n"
                + "{imp.ftl}\n"
                + "After: main.ftl\n"
                + "In main: main.ftl\n"
                + "In inc: inc.ftl\n"
                + "In inc call imp:\n"
                + "inc.ftl\n"
                + "{main.ftl}\n"
                + "In main: main.ftl\n"
                + "main.ftl\n"
                + "{main.ftl}\n"
                + "In inc call imp:\n"
                + "main.ftl\n"
                + "{main.ftl}\n"
                + "In main: main.ftl\n";
        if (allMain) {
            expected = StringUtil.replace(expected, "imp.ftl", "main.ftl");
            expected = StringUtil.replace(expected, "inc.ftl", "main.ftl");
        }
        assertOutputForNamed("main.ftl", expected);
    }

    @Before
    public void setup() {
        Configuration cfg = getConfiguration();
        cfg.setWhitespaceStripping(false);
    }
    
    @Test
    public void testInAdhocTemplate() throws TemplateException, IOException {
        StringTemplateLoader tl = new StringTemplateLoader();
        tl.putTemplate("inc.ftl", "Inc: " + PRINT_ALL_FTL);
        getConfiguration().setTemplateLoader(tl);
        
        // In nameless templates, the deprecated .templateName is "", but the new variables are missing values. 
        assertOutput(new Template(null, PRINT_ALL_FTL + "; <#include 'inc.ftl'>", getConfiguration()),
                "t=, ct=-, mt=-; Inc: t=inc.ftl, ct=inc.ftl, mt=-");
        
        assertOutput(new Template("foo.ftl", PRINT_ALL_FTL + "; <#include 'inc.ftl'>", getConfiguration()),
                "t=foo.ftl, ct=foo.ftl, mt=foo.ftl; Inc: t=inc.ftl, ct=inc.ftl, mt=foo.ftl");
    }

    @Test
    public void testInInterpretTemplate() throws TemplateException, IOException {
        getConfiguration().setSharedVariable("t", PRINT_ALL_FTL);
        assertOutput(new Template("foo.ftl", PRINT_ALL_FTL + "; <@t?interpret />", getConfiguration()),
                "t=foo.ftl, ct=foo.ftl, mt=foo.ftl; "
                + "t=foo.ftl->anonymous_interpreted, ct=foo.ftl->anonymous_interpreted, mt=foo.ftl");
        assertOutput(new Template(null, PRINT_ALL_FTL + "; <@t?interpret />", getConfiguration()),
                "t=, ct=-, mt=-; "
                + "t=nameless_template->anonymous_interpreted, ct=nameless_template->anonymous_interpreted, mt=-");
        assertOutput(new Template("foo.ftl", PRINT_ALL_FTL + "; <@[t,'bar']?interpret />", getConfiguration()),
                "t=foo.ftl, ct=foo.ftl, mt=foo.ftl; "
                + "t=foo.ftl->bar, ct=foo.ftl->bar, mt=foo.ftl");
    }

    
    @Test
    public void testArgumentBugWithMacro() throws TemplateException, IOException {
        StringTemplateLoader tl = new StringTemplateLoader();
        tl.putTemplate("main.ftl", ""
                + "<#include 'inc.ftl'>"
                + "Before: ${.currentTemplateName}\n"
                + "<@m p1=.currentTemplateName; x>"
                + "Loop var: ${x}\n"
                + "In nested: ${.currentTemplateName}\n"
                + "</@>"
                + "After: ${.currentTemplateName}");
        tl.putTemplate("inc.ftl", ""
                + "<#macro m p1 p2=.currentTemplateName>"
                + "p1: ${p1}\n"
                + "p2: ${p2}\n"
                + "Inside: ${.currentTemplateName}\n"
                + "<#nested .currentTemplateName>"
                + "</#macro>");
        Configuration cfg = getConfiguration();
        cfg.setTemplateLoader(tl);
        
        for (boolean fixed : new boolean[] { false, true }) {
            cfg.setIncompatibleImprovements(fixed ? Configuration.VERSION_2_3_28 : Configuration.VERSION_2_3_27);
            assertOutputForNamed("main.ftl", ""
                    + "Before: main.ftl\n"
                    + "p1: " + (fixed ? "main.ftl" : "inc.ftl") + "\n"
                    + "p2: inc.ftl\n"
                    + "Inside: inc.ftl\n"
                    + "Loop var: inc.ftl\n"
                    + "In nested: main.ftl\n"
                    + "After: main.ftl");
        }
    }

    @Test
    public void testArgumentBugWithFunction() throws TemplateException, IOException {
        StringTemplateLoader tl = new StringTemplateLoader();
        tl.putTemplate("main.ftl", ""
                + "<#include 'inc.ftl'>"
                + "${f(.currentTemplateName)}");
        tl.putTemplate("inc.ftl", ""
                + "<#function f(p1, p2=.currentTemplateName)>"
                + "<#return 'p1=${p1}, p2=${p2}, inside=${.currentTemplateName}'>"
                + "</#function>");
        Configuration cfg = getConfiguration();
        cfg.setTemplateLoader(tl);
        
        for (boolean fixed : new boolean[] { false, true }) {
            cfg.setIncompatibleImprovements(fixed ? Configuration.VERSION_2_3_28 : Configuration.VERSION_2_3_27);
            assertOutputForNamed("main.ftl", ""
                    + "p1=" + (fixed ? "main.ftl" : "inc.ftl")
                    + ", p2=inc.ftl, inside=inc.ftl");
        }
    }
    
}
