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

import static org.junit.Assert.*;

import java.io.IOException;
import java.io.Reader;
import java.net.URL;
import java.util.Locale;

import org.hamcrest.Matchers;
import org.junit.Test;

import com.google.common.collect.ImmutableList;

import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateNotFoundException;
import freemarker.template.Version;
import freemarker.test.MonitoredTemplateLoader;
import freemarker.test.MonitoredTemplateLoader.CloseTemplateSourceEvent;
import freemarker.test.MonitoredTemplateLoader.FindTemplateSourceEvent;
import freemarker.test.MonitoredTemplateLoader.GetLastModifiedEvent;
import freemarker.test.MonitoredTemplateLoader.GetReaderEvent;

public class TemplateCacheTest {

    @Test
    public void testCachedException() throws Exception {
        MockTemplateLoader loader = new MockTemplateLoader();
        TemplateCache cache = new TemplateCache(loader, new StrongCacheStorage());
        cache.setDelay(1000L);
        loader.setThrowException(true);
        try {
            cache.getTemplate("t", Locale.getDefault(), "", true);
            fail();
        } catch (IOException e) {
            assertEquals("mock IO exception", e.getMessage());
            assertEquals(1, loader.getFindCount());
            try {
                cache.getTemplate("t", Locale.getDefault(), "", true);
                fail();
            } catch (IOException e2) {
                // Still 1 - returned cached exception
                assertThat(e2.getMessage(),
                        Matchers.allOf(Matchers.containsString("There was an error loading the template on an " +
                        "earlier attempt")));
                assertSame(e, e2.getCause());
                assertEquals(1, loader.getFindCount());
                try {
                    Thread.sleep(1100L);
                    cache.getTemplate("t", Locale.getDefault(), "", true);
                    fail();
                } catch (IOException e3) {
                    // Cache had to retest
                    assertEquals("mock IO exception", e.getMessage());
                    assertEquals(2, loader.getFindCount());
                }
            }
        }
    }
    
    @Test
    public void testCachedNotFound() throws Exception {
        MockTemplateLoader loader = new MockTemplateLoader();
        TemplateCache cache = new TemplateCache(loader, new StrongCacheStorage(), new Configuration());
        cache.setDelay(1000L);
        cache.setLocalizedLookup(false);
        assertNull(cache.getTemplate("t", Locale.getDefault(), "", true));
        assertEquals(1, loader.getFindCount());
        assertNull(cache.getTemplate("t", Locale.getDefault(), "", true));
        // Still 1 - returned cached exception
        assertEquals(1, loader.getFindCount());
        Thread.sleep(1100L);
        assertNull(cache.getTemplate("t", Locale.getDefault(), "", true));
        // Cache had to retest
        assertEquals(2, loader.getFindCount());
    }

    private static class MockTemplateLoader implements TemplateLoader {
        private boolean throwException;
        private int findCount; 
        
        public void setThrowException(boolean throwException) {
           this.throwException = throwException;
        }
        
        public int getFindCount() {
            return findCount;
        }
        
        public void closeTemplateSource(Object templateSource)
                throws IOException {
        }

        public Object findTemplateSource(String name) throws IOException {
            ++findCount;
            if (throwException) {
                throw new IOException("mock IO exception");
            }
            return null;
        }

        public long getLastModified(Object templateSource) {
            return 0;
        }

        public Reader getReader(Object templateSource, String encoding)
                throws IOException {
            return null;
        }
        
    }
    
    @Test
    public void testManualRemovalPlain() throws IOException {
        Configuration cfg = new Configuration();
        cfg.setCacheStorage(new StrongCacheStorage());
        StringTemplateLoader loader = new StringTemplateLoader();
        cfg.setTemplateLoader(loader);
        cfg.setTemplateUpdateDelay(Integer.MAX_VALUE);
        
        loader.putTemplate("1.ftl", "1 v1");
        loader.putTemplate("2.ftl", "2 v1");
        assertEquals("1 v1", cfg.getTemplate("1.ftl").toString()); 
        assertEquals("2 v1", cfg.getTemplate("2.ftl").toString());
        
        loader.putTemplate("1.ftl", "1 v2");
        loader.putTemplate("2.ftl", "2 v2");
        assertEquals("1 v1", cfg.getTemplate("1.ftl").toString()); // no change 
        assertEquals("2 v1", cfg.getTemplate("2.ftl").toString()); // no change
        
        cfg.removeTemplateFromCache("1.ftl");
        assertEquals("1 v2", cfg.getTemplate("1.ftl").toString()); // changed 
        assertEquals("2 v1", cfg.getTemplate("2.ftl").toString());
        
        cfg.removeTemplateFromCache("2.ftl");
        assertEquals("1 v2", cfg.getTemplate("1.ftl").toString()); 
        assertEquals("2 v2", cfg.getTemplate("2.ftl").toString()); // changed
    }

    @Test
    public void testManualRemovalI18ed() throws IOException {
        Configuration cfg = new Configuration();
        cfg.setCacheStorage(new StrongCacheStorage());
        cfg.setLocale(Locale.US);
        StringTemplateLoader loader = new StringTemplateLoader();
        cfg.setTemplateLoader(loader);
        cfg.setTemplateUpdateDelay(Integer.MAX_VALUE);
        
        loader.putTemplate("1_en_US.ftl", "1_en_US v1");
        loader.putTemplate("1_en.ftl", "1_en v1");
        loader.putTemplate("1.ftl", "1 v1");
        
        assertEquals("1_en_US v1", cfg.getTemplate("1.ftl").toString());        
        assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());        
        assertEquals("1 v1", cfg.getTemplate("1.ftl", Locale.GERMANY).toString());
        
        loader.putTemplate("1_en_US.ftl", "1_en_US v2");
        loader.putTemplate("1_en.ftl", "1_en v2");
        loader.putTemplate("1.ftl", "1 v2");
        assertEquals("1_en_US v1", cfg.getTemplate("1.ftl").toString());        
        assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());        
        assertEquals("1 v1", cfg.getTemplate("1.ftl", Locale.GERMANY).toString());
        
        cfg.removeTemplateFromCache("1.ftl");
        assertEquals("1_en_US v2", cfg.getTemplate("1.ftl").toString());        
        assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());        
        assertEquals("1 v1", cfg.getTemplate("1.ftl", Locale.GERMANY).toString());
        assertEquals("1 v2", cfg.getTemplate("1.ftl", Locale.ITALY).toString());
        
        cfg.removeTemplateFromCache("1.ftl", Locale.GERMANY);
        assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());        
        assertEquals("1 v2", cfg.getTemplate("1.ftl", Locale.GERMANY).toString());

        cfg.removeTemplateFromCache("1.ftl", Locale.CANADA);
        assertEquals("1_en v1", cfg.getTemplate("1.ftl", Locale.UK).toString());
        
        cfg.removeTemplateFromCache("1.ftl", Locale.UK);
        assertEquals("1_en v2", cfg.getTemplate("1.ftl", Locale.UK).toString());        
    }

    @Test
    public void testZeroUpdateDelay() throws IOException {
        Configuration cfg = new Configuration();
        cfg.setLocale(Locale.US);
        cfg.setCacheStorage(new StrongCacheStorage());
        StringTemplateLoader loader = new StringTemplateLoader();
        cfg.setTemplateLoader(loader);
        cfg.setTemplateUpdateDelay(0);
        for (int i = 1; i <= 3; i++) {
            loader.putTemplate("t.ftl", "v" + i, i);
            assertEquals("v" + i, cfg.getTemplate("t.ftl").toString());
        }
        
        loader.putTemplate("t.ftl", "v10", 10);
        assertEquals("v10", cfg.getTemplate("t.ftl").toString());
        loader.putTemplate("t.ftl", "v11", 10); // same time stamp, different content
        assertEquals("v10", cfg.getTemplate("t.ftl").toString()); // still v10
        assertEquals("v10", cfg.getTemplate("t.ftl").toString()); // still v10
    }
    
    @Test
    public void testIncompatibleImprovementsChangesURLConCaching() throws IOException {
        Version newVersion = Configuration.VERSION_2_3_21;
        Version oldVersion = Configuration.VERSION_2_3_20;
        
        {
            Configuration cfg = new Configuration(oldVersion);
            cfg.setTemplateUpdateDelay(0);
            final MonitoredClassTemplateLoader templateLoader = new MonitoredClassTemplateLoader();
            assertNull(templateLoader.getURLConnectionUsesCaches());
            cfg.setTemplateLoader(templateLoader);
            
            assertNull(templateLoader.getLastTemplateSourceModification());
            cfg.getTemplate("test.ftl");
            assertNull(templateLoader.getLastTemplateSourceModification());
            
            cfg.setIncompatibleImprovements(newVersion);
            assertNull(templateLoader.getLastTemplateSourceModification());
            cfg.getTemplate("test.ftl");
            assertEquals(Boolean.FALSE, templateLoader.getLastTemplateSourceModification());
            
            templateLoader.setURLConnectionUsesCaches(Boolean.valueOf(true));
            templateLoader.setLastTemplateSourceModification(null);
            cfg.getTemplate("test.ftl");
            assertNull(templateLoader.getLastTemplateSourceModification());
            
            templateLoader.setURLConnectionUsesCaches(Boolean.valueOf(false));
            templateLoader.setLastTemplateSourceModification(null);
            cfg.getTemplate("test.ftl");
            assertNull(templateLoader.getLastTemplateSourceModification());

            templateLoader.setURLConnectionUsesCaches(null);
            templateLoader.setLastTemplateSourceModification(null);
            cfg.getTemplate("test.ftl");
            assertEquals(Boolean.FALSE, templateLoader.getLastTemplateSourceModification());
            
            templateLoader.setURLConnectionUsesCaches(null);
            cfg.setIncompatibleImprovements(oldVersion);
            templateLoader.setLastTemplateSourceModification(null);
            cfg.getTemplate("test.ftl");
            assertNull(templateLoader.getLastTemplateSourceModification());
            
            cfg.setTemplateLoader(new MultiTemplateLoader(
                    new TemplateLoader[] { new MultiTemplateLoader(
                                    new TemplateLoader[] { templateLoader }) }));
            cfg.setIncompatibleImprovements(newVersion);
            cfg.getTemplate("test.ftl");
            assertEquals(Boolean.FALSE, templateLoader.getLastTemplateSourceModification());
        }
    }
    
    @Test
    public void testWrongEncodingReload() throws IOException {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
        cfg.setLocale(Locale.US);
        
        MonitoredTemplateLoader tl = new MonitoredTemplateLoader();
        tl.putTemplate("utf-8_en.ftl", "<#ftl encoding='utf-8'>Foo");
        tl.putTemplate("utf-8.ftl", "Bar");
        cfg.setTemplateLoader(tl);
        
        {
            Template t = cfg.getTemplate("utf-8.ftl", "Utf-8");
            assertEquals("utf-8.ftl", t.getName());
            assertEquals("utf-8_en.ftl", t.getSourceName());
            assertEquals("Utf-8", t.getEncoding());
            assertEquals("Foo", t.toString());
            
            assertEquals(
                    ImmutableList.of(
                            new FindTemplateSourceEvent("utf-8_en_US.ftl", false),
                            new FindTemplateSourceEvent("utf-8_en.ftl", true),
                            new GetLastModifiedEvent("utf-8_en.ftl"),
                            new GetReaderEvent("utf-8_en.ftl"), // Attempt 1
                            new CloseTemplateSourceEvent("utf-8_en.ftl")),                
                    tl.getEvents());
        }
        
        {
            tl.clearEvents();
            
            Template t = cfg.getTemplate("utf-8.ftl", "Utf-16");
            assertEquals("utf-8.ftl", t.getName());
            assertEquals("utf-8_en.ftl", t.getSourceName());
            assertEquals("utf-8", t.getEncoding());
            assertEquals("Foo", t.toString());
            
            assertEquals(
                    ImmutableList.of(
                            new FindTemplateSourceEvent("utf-8_en_US.ftl", false),
                            new FindTemplateSourceEvent("utf-8_en.ftl", true),
                            new GetLastModifiedEvent("utf-8_en.ftl"),
                            new GetReaderEvent("utf-8_en.ftl"), // Attempt 1
                            new GetReaderEvent("utf-8_en.ftl"), // Attempt 2
                            new CloseTemplateSourceEvent("utf-8_en.ftl")),                
                    tl.getEvents());
        }
    }
    
    @Test
    public void testEncodingSelection() throws IOException {
        Locale hungary = new Locale("hu", "HU"); 
                
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
        cfg.setDefaultEncoding("utf-8");
        
        StringTemplateLoader tl = new StringTemplateLoader();
        tl.putTemplate("t.ftl", "Foo");
        tl.putTemplate("t_de.ftl", "Vuu");
        tl.putTemplate("t2.ftl", "<#ftl encoding='UTF-16LE'>Foo");
        tl.putTemplate("t2_de.ftl", "<#ftl encoding='UTF-16BE'>Vuu");
        cfg.setTemplateLoader(tl);

        // No locale-to-encoding mapping exists yet:
        {
            Template t = cfg.getTemplate("t.ftl", Locale.GERMANY);
            assertEquals("t.ftl", t.getName());
            assertEquals("t_de.ftl", t.getSourceName());
            assertEquals("utf-8", t.getEncoding());
            assertEquals("Vuu", t.toString());
        }
        
        cfg.setEncoding(Locale.GERMANY, "ISO-8859-1");
        cfg.setEncoding(hungary, "ISO-8859-2");
        {
            Template t = cfg.getTemplate("t.ftl", Locale.CHINESE);
            assertEquals("t.ftl", t.getName());
            assertEquals("t.ftl", t.getSourceName());
            assertEquals("utf-8", t.getEncoding());
            assertEquals("Foo", t.toString());
        }
        {
            Template t = cfg.getTemplate("t.ftl", Locale.GERMANY);
            assertEquals("t.ftl", t.getName());
            assertEquals("t_de.ftl", t.getSourceName());
            assertEquals("ISO-8859-1", t.getEncoding());
            assertEquals("Vuu", t.toString());
        }
        {
            Template t = cfg.getTemplate("t.ftl", hungary);
            assertEquals("t.ftl", t.getName());
            assertEquals("t.ftl", t.getSourceName());
            assertEquals("ISO-8859-2", t.getEncoding());
            assertEquals("Foo", t.toString());
        }
        
        // #ftl header overrides:
        {
            Template t = cfg.getTemplate("t2.ftl", Locale.CHINESE);
            assertEquals("t2.ftl", t.getName());
            assertEquals("t2.ftl", t.getSourceName());
            assertEquals("UTF-16LE", t.getEncoding());
            assertEquals("Foo", t.toString());
        }
        {
            Template t = cfg.getTemplate("t2.ftl", Locale.GERMANY);
            assertEquals("t2.ftl", t.getName());
            assertEquals("t2_de.ftl", t.getSourceName());
            assertEquals("UTF-16BE", t.getEncoding());
            assertEquals("Vuu", t.toString());
        }
        {
            Template t = cfg.getTemplate("t2.ftl", hungary);
            assertEquals("t2.ftl", t.getName());
            assertEquals("t2.ftl", t.getSourceName());
            assertEquals("UTF-16LE", t.getEncoding());
            assertEquals("Foo", t.toString());
        }
    }
    
    @Test
    public void testTemplateNameFormatExceptionAndBackwardCompatibility() throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
        
        assertNull(cfg.getTemplate("../x", null, null, null, true, true));
        try {
            cfg.getTemplate("../x");
            fail();
        } catch (TemplateNotFoundException e) {
            // expected
        }
        
        // [2.4] Test it with IcI 2.4
        
        cfg.setTemplateNameFormat(TemplateNameFormat.DEFAULT_2_4_0);
        try {
            cfg.getTemplate("../x", null, null, null, true, true);
            fail();
        } catch (MalformedTemplateNameException e) {
            // expected
        }
        try {
            cfg.getTemplate("../x");
            fail();
        } catch (MalformedTemplateNameException e) {
            // expected
        }
    }
    
    private static class MonitoredClassTemplateLoader extends ClassTemplateLoader {
        
        private Boolean lastTemplateSourceModification;

        public MonitoredClassTemplateLoader() {
            super(TemplateCacheTest.class, "");
        }

        @Override
        public Object findTemplateSource(String name) throws IOException {
            final URL url = getURL(name);
            if (url == null) return null;
            return new SpyingURLTemplateSource(url, getURLConnectionUsesCaches());
        }

        Boolean getLastTemplateSourceModification() {
            return lastTemplateSourceModification;
        }

        void setLastTemplateSourceModification(Boolean lastTemplateSourceModification) {
            this.lastTemplateSourceModification = lastTemplateSourceModification;
        }
        
        private class SpyingURLTemplateSource extends URLTemplateSource {
            
            SpyingURLTemplateSource(URL url, Boolean useCaches) throws IOException {
                super(url, useCaches);
            }

            @Override
            void setUseCaches(boolean useCaches) {
                setLastTemplateSourceModification(Boolean.valueOf(useCaches));
                super.setUseCaches(useCaches);
            }
            
        }
        
    }

}
