/*
 * 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.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.Locale;

import org.junit.Test;

import freemarker.cache.ByteArrayTemplateLoader;
import freemarker.cache.ConditionalTemplateConfigurationFactory;
import freemarker.cache.FileNameGlobMatcher;
import freemarker.cache.FirstMatchTemplateConfigurationFactory;
import freemarker.cache.MergingTemplateConfigurationFactory;
import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class TemplateConfigurationWithTemplateCacheTest {

    private static final String TEXT_WITH_ACCENTS = "pr\u00F3ba";

    private static final CustomAttribute CUST_ATT_1 = new CustomAttribute(CustomAttribute.SCOPE_TEMPLATE);
    private static final CustomAttribute CUST_ATT_2 = new CustomAttribute(CustomAttribute.SCOPE_TEMPLATE);

    @Test
    public void testEncoding() throws Exception {
        Configuration cfg = createCommonEncodingTesterConfig();
        
        {
            Template t = cfg.getTemplate("utf8.ftl");
            assertEquals("utf-8", t.getEncoding());
            assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
        }
        {
            Template t = cfg.getTemplate("utf8.ftl", "iso-8859-1");
            assertEquals("utf-8", t.getEncoding());
            assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
        }
        {
            Template t = cfg.getTemplate("utf16.ftl");
            assertEquals("utf-16", t.getEncoding());
            assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
        }
        {
            Template t = cfg.getTemplate("default.ftl");
            assertEquals("iso-8859-1", t.getEncoding());
            assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
        }
        {
            Template t = cfg.getTemplate("default.ftl", "iso-8859-5");
            assertEquals("iso-8859-5", t.getEncoding());
            assertEquals(new String(TEXT_WITH_ACCENTS.getBytes("iso-8859-1"), "iso-8859-5"),
                    getTemplateOutput(t));
        }
        {
            Template t = cfg.getTemplate("utf8-latin2.ftl");
            assertEquals("iso-8859-2", t.getEncoding());
            assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
        }
        {
            Template t = cfg.getTemplate("default-latin2.ftl");
            assertEquals("iso-8859-2", t.getEncoding());
            assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
        }
    }
    
    @Test
    public void testIncludeAndEncoding() throws Exception {
        Configuration cfg = createCommonEncodingTesterConfig();
        ByteArrayTemplateLoader tl = (ByteArrayTemplateLoader) cfg.getTemplateLoader();
        tl.putTemplate("main.ftl", (
                        "<#include 'utf8.ftl'>"
                        + "<#include 'utf16.ftl'>"
                        + "<#include 'default.ftl'>"
                        + "<#include 'utf8-latin2.ftl'>"
                        // With mostly ignored encoding params:
                        + "<#include 'utf8.ftl' encoding='utf-16'>"
                        + "<#include 'utf16.ftl' encoding='iso-8859-5'>"
                        + "<#include 'default.ftl' encoding='iso-8859-5'>"
                        + "<#include 'utf8-latin2.ftl' encoding='iso-8859-5'>"
                ).getBytes("iso-8859-1"));
        assertEquals(
                TEXT_WITH_ACCENTS + TEXT_WITH_ACCENTS + TEXT_WITH_ACCENTS + TEXT_WITH_ACCENTS
                + TEXT_WITH_ACCENTS + TEXT_WITH_ACCENTS
                + new String(TEXT_WITH_ACCENTS.getBytes("iso-8859-1"), "iso-8859-5")
                + TEXT_WITH_ACCENTS,
                getTemplateOutput(cfg.getTemplate("main.ftl")));
    }

    @Test
    public void testLocale() throws Exception {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
        cfg.setLocale(Locale.US);
        
        StringTemplateLoader tl = new StringTemplateLoader();
        tl.putTemplate("(de).ftl", "${.locale}");
        tl.putTemplate("default.ftl", "${.locale}");
        tl.putTemplate("(de)-fr.ftl",
                ("<#ftl locale='fr_FR'>${.locale}"));
        tl.putTemplate("default-fr.ftl",
                ("<#ftl locale='fr_FR'>${.locale}"));
        cfg.setTemplateLoader(tl);

        TemplateConfiguration tcDe = new TemplateConfiguration();
        tcDe.setLocale(Locale.GERMANY);
        cfg.setTemplateConfigurations(new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*(de)*"), tcDe));
        
        {
            Template t = cfg.getTemplate("(de).ftl");
            assertEquals(Locale.GERMANY, t.getLocale());
            assertEquals("de_DE", getTemplateOutput(t));
        }
        {
            Template t = cfg.getTemplate("(de).ftl", Locale.ITALY);
            assertEquals(Locale.GERMANY, t.getLocale());
            assertEquals("de_DE", getTemplateOutput(t));
        }
        {
            Template t = cfg.getTemplate("default.ftl");
            assertEquals(Locale.US, t.getLocale());
            assertEquals("en_US", getTemplateOutput(t));
        }
        {
            Template t = cfg.getTemplate("default.ftl", Locale.ITALY);
            assertEquals(Locale.ITALY, t.getLocale());
            assertEquals("it_IT", getTemplateOutput(t));
        }
    }

    @Test
    public void testPlainText() throws Exception {
        Configuration cfg = createCommonEncodingTesterConfig();
        cfg.setIncompatibleImprovements(Configuration.VERSION_2_3_22);
        
        TemplateConfiguration tcDE = new TemplateConfiguration();
        tcDE.setLocale(Locale.GERMANY);
        TemplateConfiguration tcYN = new TemplateConfiguration();
        tcYN.setBooleanFormat("Y,N");
        cfg.setTemplateConfigurations(
                    new MergingTemplateConfigurationFactory(
                            cfg.getTemplateConfigurations(),
                            new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("utf16.ftl"), tcDE),
                            new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("utf16.ftl"), tcYN)
                    )
                );
        
        {
            Template t = cfg.getTemplate("utf8.ftl", null, null, false);
            assertEquals("utf-8", t.getEncoding());
            assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
            assertEquals(Locale.US, t.getLocale());
            assertEquals("true,false", t.getBooleanFormat());
        }
        {
            Template t = cfg.getTemplate("utf8.ftl", null, "iso-8859-1", false);
            assertEquals("utf-8", t.getEncoding());
            assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
        }
        {
            Template t = cfg.getTemplate("utf16.ftl", null, null, false);
            assertEquals("utf-16", t.getEncoding());
            assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
            assertEquals(Locale.GERMANY, t.getLocale());
            assertEquals("Y,N", t.getBooleanFormat());
        }
        {
            Template t = cfg.getTemplate("default.ftl", null, null, false);
            assertEquals("iso-8859-1", t.getEncoding());
            assertEquals(TEXT_WITH_ACCENTS, getTemplateOutput(t));
        }
    }

    @Test
    public void testConfigurableSettings() throws Exception {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
        cfg.setLocale(Locale.US);
        
        TemplateConfiguration tcFR = new TemplateConfiguration();
        tcFR.setLocale(Locale.FRANCE);
        TemplateConfiguration tcYN = new TemplateConfiguration();
        tcYN.setBooleanFormat("Y,N");
        TemplateConfiguration tc00 = new TemplateConfiguration();
        tc00.setNumberFormat("0.00");
        cfg.setTemplateConfigurations(
                new MergingTemplateConfigurationFactory(
                        new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*(fr)*"), tcFR),
                        new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*(yn)*"), tcYN),
                        new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*(00)*"), tc00)
                )
        );
        
        String commonFTL = "${.locale} ${true?string} ${1.2}";
        StringTemplateLoader tl = new StringTemplateLoader();
        tl.putTemplate("default", commonFTL);
        tl.putTemplate("(fr)", commonFTL);
        tl.putTemplate("(yn)(00)", commonFTL);
        tl.putTemplate("(00)(fr)", commonFTL);
        cfg.setTemplateLoader(tl);
        
        assertEquals("en_US true 1.2", getTemplateOutput(cfg.getTemplate("default")));
        assertEquals("fr_FR true 1,2", getTemplateOutput(cfg.getTemplate("(fr)")));
        assertEquals("en_US Y 1.20", getTemplateOutput(cfg.getTemplate("(yn)(00)")));
        assertEquals("fr_FR true 1,20", getTemplateOutput(cfg.getTemplate("(00)(fr)")));
    }
    
    @Test
    public void testCustomAttributes() throws Exception {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
        
        TemplateConfiguration tc1 = new TemplateConfiguration();
        tc1.setCustomAttribute("a1", "a1tc1");
        tc1.setCustomAttribute("a2", "a2tc1");
        tc1.setCustomAttribute("a3", "a3tc1");
        CUST_ATT_1.set("ca1tc1", tc1);
        CUST_ATT_2.set("ca2tc1", tc1);
        
        TemplateConfiguration tc2 = new TemplateConfiguration();
        tc2.setCustomAttribute("a1", "a1tc2");
        CUST_ATT_1.set("ca1tc2", tc2);
        
        cfg.setTemplateConfigurations(
                new MergingTemplateConfigurationFactory(
                        new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*(tc1)*"), tc1),
                        new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*(tc2)*"), tc2)
                )
        );
        
        String commonFTL = "<#ftl attributes={ 'a3': 'a3temp' }>";
        StringTemplateLoader tl = new StringTemplateLoader();
        tl.putTemplate("(tc1)", commonFTL);
        tl.putTemplate("(tc1)noHeader", "");
        tl.putTemplate("(tc2)", commonFTL);
        tl.putTemplate("(tc1)(tc2)", commonFTL);
        cfg.setTemplateLoader(tl);

        {
            Template t = cfg.getTemplate("(tc1)");
            assertEquals("a1tc1", t.getCustomAttribute("a1"));
            assertEquals("a2tc1", t.getCustomAttribute("a2"));
            assertEquals("a3temp", t.getCustomAttribute("a3"));
            assertEquals("ca1tc1", CUST_ATT_1.get(t));
            assertEquals("ca2tc1", CUST_ATT_2.get(t));
        }
        {
            Template t = cfg.getTemplate("(tc1)noHeader");
            assertEquals("a1tc1", t.getCustomAttribute("a1"));
            assertEquals("a2tc1", t.getCustomAttribute("a2"));
            assertEquals("a3tc1", t.getCustomAttribute("a3"));
            assertEquals("ca1tc1", CUST_ATT_1.get(t));
            assertEquals("ca2tc1", CUST_ATT_2.get(t));
        }
        {
            Template t = cfg.getTemplate("(tc2)");
            assertEquals("a1tc2", t.getCustomAttribute("a1"));
            assertNull(t.getCustomAttribute("a2"));
            assertEquals("a3temp", t.getCustomAttribute("a3"));
            assertEquals("ca1tc2", CUST_ATT_1.get(t));
            assertNull(CUST_ATT_2.get(t));
        }
        {
            Template t = cfg.getTemplate("(tc1)(tc2)");
            assertEquals("a1tc2", t.getCustomAttribute("a1"));
            assertEquals("a2tc1", t.getCustomAttribute("a2"));
            assertEquals("a3temp", t.getCustomAttribute("a3"));
            assertEquals("ca1tc2", CUST_ATT_1.get(t));
            assertEquals("ca2tc1", CUST_ATT_2.get(t));
        }
    }
    
    private String getTemplateOutput(Template t) throws TemplateException, IOException {
        StringWriter sw = new StringWriter();
        t.process(null, sw);
        return sw.toString();
    }

    private Configuration createCommonEncodingTesterConfig() throws UnsupportedEncodingException {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
        cfg.setDefaultEncoding("iso-8859-1");
        cfg.setLocale(Locale.US);
        
        ByteArrayTemplateLoader tl = new ByteArrayTemplateLoader();
        tl.putTemplate("utf8.ftl", TEXT_WITH_ACCENTS.getBytes("utf-8"));
        tl.putTemplate("utf16.ftl", TEXT_WITH_ACCENTS.getBytes("utf-16"));
        tl.putTemplate("default.ftl", TEXT_WITH_ACCENTS.getBytes("iso-8859-2"));
        tl.putTemplate("utf8-latin2.ftl",
                ("<#ftl encoding='iso-8859-2'>" + TEXT_WITH_ACCENTS).getBytes("iso-8859-2"));
        tl.putTemplate("default-latin2.ftl",
                ("<#ftl encoding='iso-8859-2'>" + TEXT_WITH_ACCENTS).getBytes("iso-8859-2"));
        cfg.setTemplateLoader(tl);
        
        TemplateConfiguration tcUtf8 = new TemplateConfiguration();
        tcUtf8.setEncoding("utf-8");
        TemplateConfiguration tcUtf16 = new TemplateConfiguration();
        tcUtf16.setEncoding("utf-16");
        cfg.setTemplateConfigurations(
                new FirstMatchTemplateConfigurationFactory(
                        new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*utf8*"), tcUtf8),
                        new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*utf16*"), tcUtf16)
                ).allowNoMatch(true));
        return cfg;
    }

}
