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

import junit.framework.TestCase;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.utility.StringUtil;

/**
 * Test various generated templates (permutations), including some deliberately
 * wrong ones, with various tag_syntax settings.  
 */
public class TagSyntaxVariationsTest extends TestCase {
    
    private static final String HDR_ANG = "<#ftl>";
    private static final String HDR_SQU = squarify(HDR_ANG);
    private static final String IF_ANG = "<#if true>i</#if>";
    private static final String IF_SQU = squarify(IF_ANG);
    private static final String IF_OUT = "i";
    private static final String ASSIGN_ANG = "<#assign x = 1>a";
    private static final String ASSIGN_SQU = squarify(ASSIGN_ANG);
    private static final String ASSIGN_OUT = "a";
    private static final String WRONG_ANG = "<#wrong>";
    private static final String WRONG_SQU = squarify(WRONG_ANG);
    private static final String WRONGC_ANG = "</#wrong>";
    private static final String WRONGC_SQU = squarify(WRONGC_ANG );
    private static final String CUST_ANG = "<@compress> z </@>";
    private static final String CUST_SQU = squarify(CUST_ANG);
    private static final String CUST_OUT = "z";
    
    public TagSyntaxVariationsTest(String name) {
        super(name);
    }
    
    private static String squarify(String s) {
        return s.replace('<', '[').replace('>', ']');
    }

    public final void test()
            throws TemplateException, IOException {
        Configuration cfgBuggy = new Configuration();
        // Default on 2.3.x: cfgBuggy.setEmulate23ParserBugs(true);
        // Default on 2.3.x: cfgBuggy.setTagSyntax(Configuration.ANGLE_BRACKET_TAG_SYNTAX);
        
        Configuration cfgFixed = new Configuration();
        cfgFixed.setIncompatibleImprovements(Configuration.VERSION_2_3_19);
        // Default on 2.3.x: cfgFixed.setTagSyntax(Configuration.ANGLE_BRACKET_TAG_SYNTAX);

        // Permutations 
        for (int ifOrAssign = 0; ifOrAssign < 2; ifOrAssign++) {
            String dir_ang = ifOrAssign == 0 ? IF_ANG : ASSIGN_ANG; 
            String dir_squ = ifOrAssign == 0 ? IF_SQU : ASSIGN_SQU; 
            String dir_out = ifOrAssign == 0 ? IF_OUT : ASSIGN_OUT; 
            
            // Permutations 
            for (int angOrSqu = 0; angOrSqu < 2; angOrSqu++) {
                cfgBuggy.setTagSyntax(angOrSqu == 0
                        ? Configuration.ANGLE_BRACKET_TAG_SYNTAX
                        : Configuration.SQUARE_BRACKET_TAG_SYNTAX);
                cfgFixed.setTagSyntax(angOrSqu == 0
                        ? Configuration.ANGLE_BRACKET_TAG_SYNTAX
                        : Configuration.SQUARE_BRACKET_TAG_SYNTAX);
                
                String dir_xxx = angOrSqu == 0 ? dir_ang : dir_squ;
                String cust_xxx = angOrSqu == 0 ? CUST_ANG : CUST_SQU;
                String hdr_xxx = angOrSqu == 0 ? HDR_ANG : HDR_SQU;
                String wrong_xxx = angOrSqu == 0 ? WRONG_ANG : WRONG_SQU;
                String wrongc_xxx = angOrSqu == 0 ? WRONGC_ANG : WRONGC_SQU;
                
                test(cfgBuggy,
                        dir_xxx + cust_xxx,
                        dir_out + CUST_OUT);
                test(cfgFixed,
                        dir_xxx + cust_xxx,
                        dir_out + CUST_OUT);
                
                // Permutations 
                for (int wrongOrWrongc = 0; wrongOrWrongc < 2; wrongOrWrongc++) {
                    String wrongx_xxx = wrongOrWrongc == 0 ? wrong_xxx : wrongc_xxx;
                    
                    // Bug: initial unknown # tags are treated as static text
                    test(cfgBuggy,
                            wrongx_xxx + dir_xxx,
                            wrongx_xxx + dir_out);
                    test(cfgFixed,
                            wrongx_xxx + dir_xxx,
                            null);
    
                    // Bug: same as above
                    test(cfgBuggy,
                            wrongx_xxx + wrongx_xxx + dir_xxx,
                            wrongx_xxx + wrongx_xxx + dir_out);
                    
                    test(cfgBuggy,
                            dir_xxx + wrongx_xxx,
                            null);
                    test(cfgFixed,
                            dir_xxx + wrongx_xxx,
                            null);
                    
                    test(cfgBuggy,
                            hdr_xxx + wrongx_xxx,
                            null);
                    test(cfgFixed,
                            hdr_xxx + wrongx_xxx,
                            null);
                    
                    test(cfgBuggy,
                            cust_xxx + wrongx_xxx + dir_xxx,
                            null);
                    test(cfgFixed,
                            cust_xxx + wrongx_xxx + dir_xxx,
                            null);
                } // for wrongc
            } // for squ
            
            cfgBuggy.setTagSyntax(Configuration.AUTO_DETECT_TAG_SYNTAX);
            cfgFixed.setTagSyntax(Configuration.AUTO_DETECT_TAG_SYNTAX);
            for (int perm = 0; perm < 4; perm++) {
                // All 4 permutations
                String wrong_xxx = (perm & 1) == 0 ? WRONG_ANG : WRONG_SQU;
                String dir_xxx = (perm & 2) == 0 ? dir_ang : dir_squ;
                
                // Bug: Auto-detection ignores unknown # tags
                test(cfgBuggy,
                        wrong_xxx + dir_xxx,
                        wrong_xxx + dir_out);
                test(cfgFixed,
                        wrong_xxx + dir_xxx,
                        null);
                
                // Bug: same as above
                test(cfgBuggy,
                        wrong_xxx + wrong_xxx + dir_xxx,
                        wrong_xxx + wrong_xxx + dir_out);
            } // for perm
    
            // Permutations 
            for (int angOrSquStart = 0; angOrSquStart < 2; angOrSquStart++) {
                String hdr_xxx = angOrSquStart == 0 ? HDR_ANG : HDR_SQU;
                String cust_xxx = angOrSquStart == 0 ? CUST_ANG : CUST_SQU;
                String wrong_yyy = angOrSquStart != 0 ? WRONG_ANG : WRONG_SQU;
                String dir_xxx = angOrSquStart == 0 ? dir_ang : dir_squ;
                String dir_yyy = angOrSquStart != 0 ? dir_ang : dir_squ;
                
                test(cfgBuggy,
                        cust_xxx + wrong_yyy + dir_xxx,
                        CUST_OUT + wrong_yyy + dir_out);
                test(cfgFixed,
                        cust_xxx + wrong_yyy + dir_xxx,
                        CUST_OUT + wrong_yyy + dir_out);
                
                test(cfgBuggy,
                        hdr_xxx + wrong_yyy + dir_xxx,
                        wrong_yyy + dir_out);
                test(cfgFixed,
                        hdr_xxx + wrong_yyy + dir_xxx,
                        wrong_yyy + dir_out);
                
                test(cfgBuggy,
                        cust_xxx + wrong_yyy + dir_yyy,
                        CUST_OUT + wrong_yyy + dir_yyy);
                test(cfgFixed,
                        cust_xxx + wrong_yyy + dir_yyy,
                        CUST_OUT + wrong_yyy + dir_yyy);
                
                test(cfgBuggy,
                        hdr_xxx + wrong_yyy + dir_yyy,
                        wrong_yyy + dir_yyy);
                test(cfgFixed,
                        hdr_xxx + wrong_yyy + dir_yyy,
                        wrong_yyy + dir_yyy);
                
                test(cfgBuggy,
                        dir_xxx + wrong_yyy + dir_yyy,
                        dir_out + wrong_yyy + dir_yyy);
                test(cfgFixed,
                        dir_xxx + wrong_yyy + dir_yyy,
                        dir_out + wrong_yyy + dir_yyy);
            } // for squStart
            
        } // for assign
    }
    
    /**
     * @param expected the expected output or <tt>null</tt> if we expect
     * a parsing error.
     */
    private static final void test(
            Configuration cfg, String template, String expected)
            throws TemplateException, IOException {
        Template t = null;
        try {
            t = new Template("string", new StringReader(template), cfg);
        } catch (ParseException e) {
            if (expected != null) {
                fail("Couldn't create Template from "
                        + StringUtil.jQuote(template) + ": " + e);
            } else {
                return;
            }
        }
        if (expected == null) fail("Template parsing should have fail for "
                + StringUtil.jQuote(template));
        
        StringWriter out = new StringWriter();
        t.process(new Object(), out);
        assertEquals(expected, out.toString());
    }

}
