/*
 * 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.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.junit.Test;

import freemarker.template.Configuration;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateScalarModel;
import freemarker.template.utility.ObjectFactory;
import freemarker.test.TemplateTest;

public class DirectiveCallPlaceTest extends TemplateTest {
    
    @Override
    protected Configuration createConfiguration() {
        return new Configuration(Configuration.VERSION_2_3_22);
    }
    
    @Test
    public void testCustomDataBasics() throws IOException, TemplateException {
        addTemplate(
                "customDataBasics.ftl",
                "<@uc>Abc</@uc> <@uc>x=${x}</@uc> <@uc>Ab<#-- -->c</@uc> <@lc/><@lc></@lc> <@lc>Abc</@lc>");
        
        CachingTextConverterDirective.resetCacheRecreationCount();
        for (int i = 0; i < 3; i++) {
            assertOutputForNamed(
                    "customDataBasics.ftl",
                    "ABC[cached 1] X=123 ABC[cached 2]  abc[cached 3]");
        }
    }

    @Test
    public void testCustomDataProviderMismatch() throws IOException, TemplateException {
        addTemplate(
                "customDataProviderMismatch.ftl",
                "<#list [uc, lc, uc] as d><#list 1..2 as _><@d>Abc</@d></#list></#list>");
        
        CachingTextConverterDirective.resetCacheRecreationCount();
        assertOutputForNamed(
                "customDataProviderMismatch.ftl",
                "ABC[cached 1]ABC[cached 1]abc[cached 2]abc[cached 2]ABC[cached 3]ABC[cached 3]");
        assertOutputForNamed(
                "customDataProviderMismatch.ftl",
                "ABC[cached 3]ABC[cached 3]abc[cached 4]abc[cached 4]ABC[cached 5]ABC[cached 5]");
    }
    
    @Test
    public void testPositions() throws IOException, TemplateException {
        addTemplate(
                "positions.ftl",
                "<@pa />\n"
                + "..<@pa\n"
                + "/><@pa>xxx</@>\n"
                + "<@pa>{<@pa/> <@pa/>}</@>\n"
                + "${curDirLine}<@argP p=curDirLine?string>${curDirLine}</@argP>${curDirLine}\n"
                + "<#macro m p>(p=${p}){<#nested>}</#macro>\n"
                + "${curDirLine}<@m p=curDirLine?string>${curDirLine}</@m>${curDirLine}");
        
        assertOutputForNamed(
                "positions.ftl",
                "[positions.ftl:1:1-1:7]"
                + "..[positions.ftl:2:3-3:2]"
                + "[positions.ftl:3:3-3:14]xxx\n"
                + "[positions.ftl:4:1-4:24]{[positions.ftl:4:7-4:12] [positions.ftl:4:14-4:19]}\n"
                + "-(p=5){-}-\n"
                + "-(p=7){-}-"
                );
    }
    
    @SuppressWarnings("boxing")
    @Override
    protected Object createDataModel() {
        Map<String, Object> dm = new HashMap<>();
        dm.put("uc", new CachingUpperCaseDirective());
        dm.put("lc", new CachingLowerCaseDirective());
        dm.put("pa", new PositionAwareDirective());
        dm.put("argP", new ArgPrinterDirective());
        dm.put("curDirLine", new CurDirLineScalar());
        dm.put("x", 123);
        return dm;
    }

    private abstract static class CachingTextConverterDirective implements TemplateDirectiveModel {

        /** Only needed for testing. */
        private static AtomicInteger cacheRecreationCount = new AtomicInteger();
        
        /** Only needed for testing. */
        static void resetCacheRecreationCount() {
            cacheRecreationCount.set(0);
        }
        
        public void execute(Environment env, Map params, TemplateModel[] loopVars, final TemplateDirectiveBody body)
                throws TemplateException, IOException {
            if (body == null) {
                return;
            }
            
            final String convertedText;

            final DirectiveCallPlace callPlace = env.getCurrentDirectiveCallPlace();
            if (callPlace.isNestedOutputCacheable()) {
                try {
                    convertedText = (String) callPlace.getOrCreateCustomData(
                            getTextConversionIdentity(), new ObjectFactory<String>() {

                                public String createObject() throws TemplateException, IOException {
                                    return convertBodyText(body)
                                            + "[cached " + cacheRecreationCount.incrementAndGet() + "]";
                                }

                            });
                } catch (CallPlaceCustomDataInitializationException e) {
                    throw new TemplateModelException("Failed to pre-render nested content", e);
                }
            } else {
                convertedText = convertBodyText(body);
            }

            env.getOut().write(convertedText);
        }

        protected abstract Class getTextConversionIdentity();

        private String convertBodyText(TemplateDirectiveBody body) throws TemplateException,
                IOException {
            StringWriter sw = new StringWriter();
            body.render(sw);
            return convertText(sw.toString());
        }
        
        protected abstract String convertText(String s);

    }
    
    private static class CachingUpperCaseDirective extends CachingTextConverterDirective {

        @Override
        protected String convertText(String s) {
            return s.toUpperCase();
        }
        
        @Override
        protected Class getTextConversionIdentity() {
            return CachingUpperCaseDirective.class;
        }
        
    }

    private static class CachingLowerCaseDirective extends CachingTextConverterDirective {

        @Override
        protected String convertText(String s) {
            return s.toLowerCase();
        }

        @Override
        protected Class getTextConversionIdentity() {
            return CachingLowerCaseDirective.class;
        }
        
    }
    
    private static class PositionAwareDirective implements TemplateDirectiveModel {

        public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
                throws TemplateException, IOException {
            Writer out = env.getOut();
            DirectiveCallPlace callPlace = env.getCurrentDirectiveCallPlace();
            out.write("[");
            out.write(callPlace.getTemplate().getSourceName());
            out.write(":");
            out.write(Integer.toString(callPlace.getBeginLine()));
            out.write(":");
            out.write(Integer.toString(callPlace.getBeginColumn()));
            out.write("-");
            out.write(Integer.toString(callPlace.getEndLine()));
            out.write(":");
            out.write(Integer.toString(callPlace.getEndColumn()));
            out.write("]");
            if (body != null) {
                body.render(out);
            }
        }

    }

    private static class ArgPrinterDirective implements TemplateDirectiveModel {

        public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
                throws TemplateException, IOException {
            final Writer out = env.getOut();
            if (params.size() > 0) {
                out.write("(p=");
                out.write(((TemplateScalarModel) params.get("p")).getAsString());
                out.write(")");
            }
            if (body != null) {
                out.write("{");
                body.render(out);
                out.write("}");
            }
        }
        
    }
    
    private static class CurDirLineScalar implements TemplateScalarModel {

        public String getAsString() throws TemplateModelException {
            DirectiveCallPlace callPlace = Environment.getCurrentEnvironment().getCurrentDirectiveCallPlace();
            return callPlace != null
                    ? String.valueOf(Environment.getCurrentEnvironment().getCurrentDirectiveCallPlace().getBeginLine())
                    : "-";
        }
        
    }

}
