/*
 * 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 org.junit.internal.runners.JUnit38ClassRunner;
import org.junit.runner.RunWith;

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

/**
 * Test various generated templates (permutations), including some deliberately
 * wrong ones, with various tag_syntax settings.  
 */
@RunWith(JUnit38ClassRunner.class)
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 {@code null} 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());
    }

}
