/*
 * 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 static org.junit.Assert.*;

import java.io.IOException;
import java.io.Writer;
import java.util.Collections;
import java.util.Map;

import org.junit.Test;

import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.SimpleScalar;
import freemarker.template.Template;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.Version;
import freemarker.test.TemplateTest;

public class EnvironmentGetTemplateVariantsTest extends TemplateTest {

    private static final StringTemplateLoader TEMPLATES = new StringTemplateLoader();
    static {
        TEMPLATES.putTemplate("main",
                "<@tNames />\n"
                + "---1---\n"
                + "[imp: <#import 'imp' as i>${i.impIni}]\n"
                + "---2---\n"
                + "<@i.impM>"
                    + "<@tNames />"
                + "</@>\n"
                + "---3---\n"
                + "[inc: <#include 'inc'>]\n"
                + "---4---\n"
                + "<@incM>"
                    + "<@tNames />"
                + "</@>\n"
                + "---5---\n"
                + "[inc2: <#include 'inc2'>]\n"
                + "---6---\n"
                + "<#import 'imp2' as i2>"
                + "<@i.impM2><@tNames /></@>\n"
                + "---7---\n"
                + "<#macro mainM>"
                    + "[mainM: <@tNames /> {<#nested>} <@tNames />]"
                + "</#macro>"
                + "[inc3: <#include 'inc3'>]\n"
                + "<@mainM><@tNames /> <#include 'inc4'> <@tNames /></@>\n"
                + "<@tNames />\n"
                + "---8---\n"
                + "<#function mainF>"
                    + "<@tNames />"
                    + "<#return lastTNamesResult>"
                + "</#function>"
                + "mainF: ${mainF()}, impF: ${i.impF()}, incF: ${incF()}\n"
                );
        TEMPLATES.putTemplate("inc",
                "<@tNames />\n"
                + "<#macro incM>"
                    + "[incM: <@tNames /> {<#nested>}]"
                + "</#macro>"
                + "<#function incF>"
                    + "<@tNames />"
                    + "<#return lastTNamesResult>"
                + "</#function>"
                + "<@incM><@tNames /></@>\n"
                + "<#if !included!false>[incInc: <#assign included=true><#include 'inc'>]\n</#if>"
                );
        TEMPLATES.putTemplate("imp",
                "<#assign impIni><@tNames /></#assign>\n"
                + "<#macro impM>"
                    + "[impM: <@tNames />\n"
                        + "{<#nested>}\n"
                        + "[inc: <#include 'inc'>]\n"
                        + "<@incM><@tNames /></@>\n"
                    + "]"
                + "</#macro>"
                + "<#macro impM2>"
                    + "[impM2: <@tNames />\n"
                    + "{<#nested>}\n"
                    + "<@i2.imp2M><@tNames /></@>\n"
                    + "]"
                + "</#macro>"
                + "<#function impF>"
                    + "<@tNames />"
                    + "<#return lastTNamesResult>"
                + "</#function>"
                );
        TEMPLATES.putTemplate("inc2",
                "<@tNames />\n"
                + "<@i.impM><@tNames /></@>\n"
                );
        TEMPLATES.putTemplate("imp2",
                "<#macro imp2M>"
                    + "[imp2M: <@tNames /> {<#nested>}]"
                + "</#macro>");
        TEMPLATES.putTemplate("inc3",
                "<@tNames />\n"
                + "<@mainM><@tNames /></@>\n"
                );
        TEMPLATES.putTemplate("inc4",
                "<@tNames />"
                );
        
        TEMPLATES.putTemplate("FM23MacroNsBug/main",
                "<#include 'inc'>"
                + "<#assign ns = 'main'>"
                + "<@m />\n"
                + "<#import 'inc' as i>"
                + "<@i.m />\n"
                + "<@m />\n");
        TEMPLATES.putTemplate("FM23MacroNsBug/inc",
                "<#assign ns = 'inc'>"
                + "<#macro m>"
                    + "ns: ${ns}"
                + "</#macro>");
    }
    
    private final static String EXPECTED_2_3_21 =
            "<t=main ct=main mt=main>\n"
            + "---1---\n"
            + "[imp: <t=imp ct=imp mt=main>]\n"
            + "---2---\n"
            + "[impM: <t=main ct=imp mt=main>\n"
                + "{<t=main ct=main mt=main>}\n"
                + "[inc: <t=inc ct=inc cnst=imp mt=main>\n"
                    + "[incM: <t=inc ct=inc cnst=imp mt=main> {<t=imp ct=inc cnst=imp mt=main>}]\n"
                    + "[incInc: <t=inc ct=inc cnst=imp mt=main>\n"
                        + "[incM: <t=inc ct=inc cnst=imp mt=main> {<t=imp ct=inc cnst=imp mt=main>}]\n"
                    + "]\n"
                + "]\n"
                + "[incM: <t=main ct=inc cnst=imp mt=main> {<t=imp ct=imp mt=main>}]\n"
            + "]\n"
            + "---3---\n"
            + "[inc: <t=inc ct=inc cnst=main mt=main>\n"
                + "[incM: <t=inc ct=inc cnst=main mt=main> {<t=main ct=inc cnst=main mt=main>}]\n"
                + "[incInc: <t=inc ct=inc cnst=main mt=main>\n"
                    + "[incM: <t=inc ct=inc cnst=main mt=main> {<t=main ct=inc cnst=main mt=main>}]\n"
                + "]\n"
            + "]\n"
            + "---4---\n"
            + "[incM: <t=main ct=inc cnst=main mt=main> {<t=main ct=main mt=main>}]\n"
            + "---5---\n"
            + "[inc2: <t=inc2 ct=inc2 cnst=main mt=main>\n"
                + "[impM: <t=inc2 ct=imp mt=main>\n"
                    + "{<t=main ct=inc2 cnst=main mt=main>}\n"
                    + "[inc: <t=inc ct=inc cnst=imp mt=main>\n"
                        + "[incM: <t=inc ct=inc cnst=imp mt=main> {<t=imp ct=inc cnst=imp mt=main>}]\n"
                    + "]\n"
                    + "[incM: <t=inc2 ct=inc cnst=imp mt=main> {<t=imp ct=imp mt=main>}]\n"
                + "]\n"
            + "]\n"
            + "---6---\n"
            + "[impM2: <t=main ct=imp mt=main>\n"
                + "{<t=main ct=main mt=main>}\n"
                + "[imp2M: <t=main ct=imp2 mt=main> {<t=imp ct=imp mt=main>}]\n"
            + "]\n"
            + "---7---\n"
            + "[inc3: <t=inc3 ct=inc3 cnst=main mt=main>\n"
                + "[mainM: <t=inc3 ct=main mt=main> {<t=main ct=inc3 cnst=main mt=main>} <t=inc3 ct=main mt=main>]\n"
            + "]\n"
            + "[mainM: "
                + "<t=main ct=main mt=main> "
                + "{<t=main ct=main mt=main> <t=inc4 ct=inc4 cnst=main mt=main> <t=main ct=main mt=main>} "
                + "<t=main ct=main mt=main>"
            + "]\n"
            + "<t=main ct=main mt=main>\n"
            + "---8---\n"
            + "mainF: <t=main ct=main mt=main>, impF: <t=main ct=imp mt=main>, "
            + "incF: <t=main ct=inc cnst=main mt=main>\n";
    
    @Test
    public void test2321() throws IOException, TemplateException {
        setConfiguration(createConfiguration(Configuration.VERSION_2_3_21));
        assertOutputForNamed("main", EXPECTED_2_3_21);
    }

    @Test
    public void test2322() throws IOException, TemplateException {
        setConfiguration(createConfiguration(Configuration.VERSION_2_3_22));
        assertOutputForNamed("main", EXPECTED_2_3_21.replaceAll("<t=\\w+", "<t=main"));
    }

    @Test
    public void testNotStarted() throws IOException, TemplateException {
        Template t = new Template("foo", "", createConfiguration(Configuration.VERSION_2_3_21));
        final Environment env = t.createProcessingEnvironment(null, null);
        assertSame(t, env.getMainTemplate());
        assertSame(t, env.getCurrentTemplate());
    }

    @Test
    public void testFM23MacroNsBugFixed() throws IOException, TemplateException {
        setConfiguration(createConfiguration(Configuration.VERSION_2_3_0));
        assertOutputForNamed("FM23MacroNsBug/main",
                "ns: main\n"
                + "ns: inc\n"
                + "ns: main\n");
    }
    
    private Configuration createConfiguration(Version iciVersion) {
        Configuration cfg = new Configuration(iciVersion);
        cfg.setTemplateLoader(TEMPLATES);
        cfg.setWhitespaceStripping(false);
        return cfg;
    }

    @Override
    protected Object createDataModel() {
        return Collections.singletonMap("tNames", new TemplateDirectiveModel() {

            public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
                    throws TemplateException, IOException {
                Writer out = env.getOut();
                final Template currentTemplate = env.getCurrentTemplate();
                final Template curNsTemplate = env.getCurrentNamespace().getTemplate();
                final String r = "<t=" + env.getTemplate().getName() + " ct=" + currentTemplate.getName()
                        + (curNsTemplate == currentTemplate ? "" : " cnst=" + curNsTemplate.getName())
                        + " mt=" + env.getMainTemplate().getName() + ">";
                out.write(r);
                env.setGlobalVariable("lastTNamesResult", new SimpleScalar(r));
            }
            
        });
    }

}
