/*
 * 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.template;

import static freemarker.test.hamcerst.Matchers.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;

import org.junit.Test;

import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.StringTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.cache.TemplateLookupContext;
import freemarker.cache.TemplateLookupResult;
import freemarker.cache.TemplateLookupStrategy;
import freemarker.cache.WebappTemplateLoader;

public class TemplateNotFoundMessageTest {

    @Test
    public void testFileTemplateLoader() throws IOException {
        final File baseDir = new File(System.getProperty("user.home"));
        final String errMsg = failWith(new FileTemplateLoader(baseDir));
        showErrorMessage(errMsg);
        assertThat(errMsg, containsString(baseDir.toString()));
        assertThat(errMsg, containsString("FileTemplateLoader"));
    }

    @Test
    public void testClassTemplateLoader() throws IOException {
        final String errMsg = failWith(new ClassTemplateLoader(this.getClass(), "foo/bar"));
        showErrorMessage(errMsg);
        assertThat(errMsg, containsString("ClassTemplateLoader"));
        assertThat(errMsg, containsString("foo/bar"));
    }

    @Test
    public void testWebappTemplateLoader() throws IOException {
        final String errMsg = failWith(new WebappTemplateLoader(new MockServletContext(), "WEB-INF/templates"));
        showErrorMessage(errMsg);
        assertThat(errMsg, containsString("WebappTemplateLoader"));
        assertThat(errMsg, containsString("MyApp"));
        assertThat(errMsg, containsString("WEB-INF/templates"));
    }

    @Test
    public void testStringTemplateLoader() throws IOException {
        StringTemplateLoader tl = new StringTemplateLoader();
        tl.putTemplate("aaa", "A");
        tl.putTemplate("bbb", "B");
        tl.putTemplate("ccc", "C");
        final String errMsg = failWith(tl);
        showErrorMessage(errMsg);
        assertThat(errMsg, containsString("StringTemplateLoader"));
        assertThat(errMsg, containsString("aaa"));
        assertThat(errMsg, containsString("bbb"));
        assertThat(errMsg, containsString("ccc"));
    }
    
    @Test
    public void testMultiTemplateLoader() throws IOException {
        final String errMsg = failWith(new MultiTemplateLoader(new TemplateLoader[] {
                new WebappTemplateLoader(new MockServletContext(), "WEB-INF/templates"),
                new ClassTemplateLoader(this.getClass(), "foo/bar")
        }));
        showErrorMessage(errMsg);
        assertThat(errMsg, containsString("MultiTemplateLoader"));
        assertThat(errMsg, containsString("WebappTemplateLoader"));
        assertThat(errMsg, containsString("MyApp"));
        assertThat(errMsg, containsString("WEB-INF/templates"));
        assertThat(errMsg, containsString("ClassTemplateLoader"));
        assertThat(errMsg, containsString("foo/bar"));
    }

    @Test
    public void testDefaultTemplateLoader() throws IOException {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
        {
            String errMsg = failWith(cfg);
            showErrorMessage(errMsg);
            assertThat(errMsg, allOf(containsString("setTemplateLoader"), containsString("dangerous")));
        }
        {
            cfg.setIncompatibleImprovements(Configuration.VERSION_2_3_21);
            String errMsg = failWith(cfg);
            showErrorMessage(errMsg);
            assertThat(errMsg, allOf(containsString("setTemplateLoader"), containsString("null")));
        }
    }
    
    @Test
    public void testOtherMessageDetails() throws IOException {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
        cfg.setTemplateLoader(new StringTemplateLoader());
        
        {
            String errMsg = failWith("../x", cfg);
            showErrorMessage(errMsg);
            assertThat(errMsg,
                    allOf(containsStringIgnoringCase("reason"), containsStringIgnoringCase("root directory")));
        }
        {
            String errMsg = failWith("x\u0000y", cfg);
            showErrorMessage(errMsg);
            assertThat(errMsg,
                    allOf(containsStringIgnoringCase("reason"), containsStringIgnoringCase("null character")));
        }
        {
            String errMsg = failWith("x\\y", cfg);
            showErrorMessage(errMsg);
            assertThat(errMsg,
                    allOf(containsStringIgnoringCase("warning"), containsStringIgnoringCase("backslash")));
        }
        {
            String errMsg = failWith("x/./y", cfg);
            showErrorMessage(errMsg);
            assertThat(errMsg,
                    allOf(containsStringIgnoringCase("normalized"), containsStringIgnoringCase("x/y")));
        }
        {
            String errMsg = failWith("/x/y", cfg);
            showErrorMessage(errMsg);
            assertThat(errMsg, not(containsStringIgnoringCase("normalized")));
        }
        {
            String errMsg = failWith("x/y", cfg);
            showErrorMessage(errMsg);
            assertThat(errMsg, not(containsStringIgnoringCase("normalized")));
            assertThat(errMsg, not(containsStringIgnoringCase("lookup strategy")));
        }
        
        cfg.setTemplateLookupStrategy(new TemplateLookupStrategy() {
            @Override
            public TemplateLookupResult lookup(TemplateLookupContext ctx) throws IOException {
                return ctx.lookupWithAcquisitionStrategy(ctx.getTemplateName());
            }
        });
        {
            String errMsg = failWith("x/y", cfg);
            showErrorMessage(errMsg);
            assertThat(errMsg, containsStringIgnoringCase("lookup strategy"));
        }
        
        try {
            cfg.getTemplate("./missing", null, "example.com", null, true, false);
            fail();
        } catch (TemplateNotFoundException e) {
            showErrorMessage(e.getMessage());
            assertThat(e.getMessage(), containsStringIgnoringCase("example.com"));
        }
    }

    private void showErrorMessage(String errMsg) {
        // System.out.println(errMsg);
    }

    private String failWith(TemplateLoader tl, String name, Configuration cfg) {
        if (tl != null) {
            cfg.setTemplateLoader(tl);
        }
        try {
            cfg.getTemplate(name);
            fail();
        } catch (TemplateNotFoundException e) {
            return e.getMessage();
        } catch (IOException e) {
            fail();
        }
        return null;
    }
    
    private String failWith(TemplateLoader tl) {
        return failWith(tl, "missing.ftl", new Configuration(Configuration.VERSION_2_3_21));
    }

    private String failWith(Configuration cfg) {
        return failWith(null, "missing.ftl", cfg);
    }

    private String failWith(String name, Configuration cfg) {
        return failWith(null, name, cfg);
    }

}
