/*
 * 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.util.ArrayList;
import java.util.List;

import org.junit.Test;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.utility.NullWriter;
import freemarker.template.utility.StringUtil;

public class TemplateProcessingTracerTest {

    private static final String TEMPLATE_TEXT =
            "<#if 0 == 1>Nope.\n</#if>" +
            "<#if 1 == 1>Yup.\n</#if>" +
            "Always.\n" +
            "<#list [1, 2, 3] as item>\n" +
            "${item}<#else>\n" +
            "Nope.\n" +
            "</#list>\n" +
            "<#list [] as item>\n" +
            "${item}<#else>" +
            "Yup.\n" +
            "</#list>\n" +
            "<#list 1..2 as i>${i}</#list>" +
            "<#list 1..3 as j>${j}<#sep>, </#list>" +
            "<#foreach k in 1..2>k=${k}</#foreach>" +
            "<#attempt>succeed<#recover>not visited</#attempt>" +
            "<#attempt>will fail${fail}<#recover>recover</#attempt>" +
            "<@('x'?interpret) />" +
            "<#if true>t<#else>f</#if>" +
            "<#if false>t<#else>f</#if>" +
            "<#if false>t1<#elseif false>f1<#else>f2</#if>" +
            "<#if false>t1<#elseif true>t2<#else>f2</#if>" +
            "<#switch 2>" +
            "<#case 1>C1<#break>" +
            "<#case 2>C2<#break>" +
            "<#case 3>C3<#break>" +
            "<#default>D" +
            "</#switch>" +
            "<#switch 3>" +
            "<#case 1>C1<#break>" +
            "<#case 2>C3<#break>" +
            "<#default>D" +
            "</#switch>" +
            "<#macro m>Hello from m!</#macro>" +
            "Calling macro: <@m />" +
            "<#assign t>captured</#assign>" +
            "\n";

    @Test
    public void test() throws Exception {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
        Template t = new Template("test.ftl", TEMPLATE_TEXT, cfg);
        TestTemplateProcessingTracer tracer = new TestTemplateProcessingTracer();
        Environment env = t.createProcessingEnvironment(null, NullWriter.INSTANCE);
        env.setTemplateProcessingTracer(tracer);
        env.process();

        System.out.println();
        for (String it : tracer.leafElementSourceSnippets) {
            System.out.println(StringUtil.jQuote(it) + ",");
        }
        System.out.println();
        for (String it : tracer.indentedElementDescriptions) {
            System.out.println("|" + it);
        }
        System.out.println();

        assertEquals(
                List.of(
                        "Yup.\n",
                        "Always.\n",
                        "${item}",
                        "${item}",
                        "${item}",
                        "Yup.\n",
                        "${i}",
                        "${i}",
                        "${j}",
                        ", ",
                        "${j}",
                        ", ",
                        "${j}",
                        "k=",
                        "${k}",
                        "k=",
                        "${k}",
                        "succeed",
                        "will fail",
                        "${fail}",
                        "recover",
                        "<@('x'?interpret) />",
                        "x",
                        "t",
                        "f",
                        "f2",
                        "t2",
                        "C2",
                        "<#break>",
                        "D",
                        "Calling macro: ",
                        "<@m />",
                        "Hello from m!",
                        "captured",
                        "\n"
                ),
                tracer.leafElementSourceSnippets);

        assertEquals(
                List.of(
                        "root",
                        " #if 0 == 1",
                        " #if 1 == 1",
                        "  text \"Yup.\\n\"",
                        " text \"Always.\\n\"",
                        " #list-#else-container",
                        "  #list [1, 2, 3] as item",
                        "   ${item}",
                        "   ${item}",
                        "   ${item}",
                        " #list-#else-container",
                        "  #list [] as item",
                        "  #else",
                        "   text \"Yup.\\n\"",
                        " #list 1..2 as i",
                        "  ${i}",
                        "  ${i}",
                        " #list 1..3 as j",
                        "  ${j}",
                        "  #sep",
                        "   text \", \"",
                        "  ${j}",
                        "  #sep",
                        "   text \", \"",
                        "  ${j}",
                        "  #sep",
                        " #foreach k in 1..2",
                        "  text \"k=\"",
                        "  ${k}",
                        "  text \"k=\"",
                        "  ${k}",
                        " #attempt",
                        "  text \"succeed\"",
                        " #attempt",
                        "  #mixed_content",
                        "   text \"will fail\"",
                        "   ${fail}",
                        "  #recover",
                        "   text \"recover\"",
                        " @(\"x\"?interpret)",
                        "  text \"x\"",
                        " #if-#elseif-#else-container",
                        "  #if true",
                        "   text \"t\"",
                        " #if-#elseif-#else-container",
                        "  #else",
                        "   text \"f\"",
                        " #if-#elseif-#else-container",
                        "  #else",
                        "   text \"f2\"",
                        " #if-#elseif-#else-container",
                        "  #elseif true",
                        "   text \"t2\"",
                        " #switch 2",
                        "  #case 2",
                        "   text \"C2\"",
                        "   #break",
                        " #switch 3",
                        "  #default",
                        "   text \"D\"",
                        " #macro m",
                        " text \"Calling macro: \"",
                        " @m",
                        "  #macro m",
                        "   text \"Hello from m!\"",
                        " #assign t = .nested_output",
                        "  text \"captured\"",
                        " text \"\\n\""
                ),
                tracer.indentedElementDescriptions);
    }

    private static class TestTemplateProcessingTracer implements TemplateProcessingTracer {
        private final List<String> leafElementSourceSnippets = new ArrayList<>();
        private final List<String> indentedElementDescriptions = new ArrayList<>();
        private String indentation = null;

        public void enterElement(Environment env, TracedElement tracedElement) {
            if (indentation == null) {
                indentation = "";
            } else {
                indentation += " ";
            }

            indentedElementDescriptions.add(indentation + tracedElement.getDescription());

            if (tracedElement.isLeaf()) {
                int beginColumn = tracedElement.getBeginColumn();
                int beginLine = tracedElement.getBeginLine();
                int endLine = tracedElement.getEndLine();
                int endColumn = tracedElement.getEndColumn();

                String suffix;
                if (beginLine != endLine) {
                    endLine = beginLine;
                    endColumn = Integer.MAX_VALUE;
                    suffix = "[...]";
                } else {
                    suffix = "";
                }

                String sourceQuotation = tracedElement.getTemplate()
                        .getSource(beginColumn, beginLine, endColumn, endLine);
                leafElementSourceSnippets.add(sourceQuotation + suffix);
            }
        }

        public void exitElement(Environment env) {
            indentation = indentation.isEmpty() ? null : indentation.substring(0, indentation.length() - 1);
        }
    }
}
