/*
 * 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 org.junit.Assert.*;

import java.math.BigDecimal;

import org.junit.Test;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

import freemarker.core.CustomAttribute;
import freemarker.core.Environment;
import freemarker.template.utility.NullWriter;

@SuppressWarnings("boxing")
public class CustomAttributeTest {
    
    private static final String KEY_1 = "key1";
    private static final String KEY_2 = "key2";
    private static final String KEY_3 = "key3";
    
    private static final Object VALUE_1 = new Object();
    private static final Object VALUE_2 = new Object();
    private static final Object VALUE_3 = new Object();
    private static final Object VALUE_LIST = ImmutableList.<Object>of(
            "s", BigDecimal.valueOf(2), Boolean.TRUE, ImmutableMap.<String, String>of("a", "A"));
    private static final Object VALUE_BIGDECIMAL = BigDecimal.valueOf(22);

    private static final CustomAttribute CUST_ATT_TMP_1 = new CustomAttribute(CustomAttribute.SCOPE_TEMPLATE);
    private static final CustomAttribute CUST_ATT_TMP_2 = new CustomAttribute(CustomAttribute.SCOPE_TEMPLATE);
    private static final CustomAttribute CUST_ATT_ENV_1 = new CustomAttribute(CustomAttribute.SCOPE_ENVIRONMENT);
    private static final CustomAttribute CUST_ATT_ENV_2 = new CustomAttribute(CustomAttribute.SCOPE_ENVIRONMENT);
    private static final CustomAttribute CUST_ATT_CFG_1 = new CustomAttribute(CustomAttribute.SCOPE_CONFIGURATION);
    private static final CustomAttribute CUST_ATT_CFG_2 = new CustomAttribute(CustomAttribute.SCOPE_CONFIGURATION);
    
    @Test
    public void testStringKey() throws Exception {
        Template t = new Template(null, "", new Configuration(Configuration.VERSION_2_3_22));
        assertEquals(0, t.getCustomAttributeNames().length);        
        assertNull(t.getCustomAttribute(KEY_1));
        
        t.setCustomAttribute(KEY_1, VALUE_1);
        assertArrayEquals(new String[] { KEY_1 }, t.getCustomAttributeNames());        
        assertSame(VALUE_1, t.getCustomAttribute(KEY_1));
        
        t.setCustomAttribute(KEY_2, VALUE_2);
        assertArrayEquals(new String[] { KEY_1, KEY_2 }, t.getCustomAttributeNames());        
        assertSame(VALUE_1, t.getCustomAttribute(KEY_1));
        assertSame(VALUE_2, t.getCustomAttribute(KEY_2));
        
        t.setCustomAttribute(KEY_1, VALUE_2);
        assertArrayEquals(new String[] { KEY_1, KEY_2 }, t.getCustomAttributeNames());        
        assertSame(VALUE_2, t.getCustomAttribute(KEY_1));
        assertSame(VALUE_2, t.getCustomAttribute(KEY_2));
        
        t.setCustomAttribute(KEY_1, null);
        assertArrayEquals(new String[] { KEY_1, KEY_2 }, t.getCustomAttributeNames());        
        assertNull(t.getCustomAttribute(KEY_1));
        assertSame(VALUE_2, t.getCustomAttribute(KEY_2));
        
        t.removeCustomAttribute(KEY_1);
        assertArrayEquals(new String[] { KEY_2 }, t.getCustomAttributeNames());        
        assertNull(t.getCustomAttribute(KEY_1));
        assertSame(VALUE_2, t.getCustomAttribute(KEY_2));
    }

    @Test
    public void testRemoveFromEmptySet() throws Exception {
        Template t = new Template(null, "", new Configuration(Configuration.VERSION_2_3_22));
        t.removeCustomAttribute(KEY_1);
        assertEquals(0, t.getCustomAttributeNames().length);        
        assertNull(t.getCustomAttribute(KEY_1));
        
        t.setCustomAttribute(KEY_1, VALUE_1);
        assertArrayEquals(new String[] { KEY_1 }, t.getCustomAttributeNames());        
        assertSame(VALUE_1, t.getCustomAttribute(KEY_1));
    }
    
    @Test
    public void testFtlHeader() throws Exception {
        Template t = new Template(null, "<#ftl attributes={"
                + "'" + KEY_1 + "': [ 's', 2, true, {  'a': 'A' } ], "
                + "'" + KEY_2 + "': " + VALUE_BIGDECIMAL + " "
                + "}>",
                new Configuration(Configuration.VERSION_2_3_22));
        
        assertArrayEquals(new String[] { KEY_1, KEY_2 }, t.getCustomAttributeNames());
        assertEquals(VALUE_LIST, t.getCustomAttribute(KEY_1));
        assertEquals(VALUE_BIGDECIMAL, t.getCustomAttribute(KEY_2));
        
        t.setCustomAttribute(KEY_1, VALUE_1);
        assertEquals(VALUE_1, t.getCustomAttribute(KEY_1));
        assertEquals(VALUE_BIGDECIMAL, t.getCustomAttribute(KEY_2));
    }
    
    @Test
    public void testFtlHeader2() throws Exception {
        Template t = new Template(null, "<#ftl attributes={"
                + "'" + KEY_1 + "': 'a', "
                + "'" + KEY_2 + "': 'b', "
                + "'" + KEY_3 + "': 'c' "
                + "}>",
                new Configuration(Configuration.VERSION_2_3_22));
        
        assertArrayEquals(new String[] { KEY_1, KEY_2, KEY_3 }, t.getCustomAttributeNames());
        assertEquals("a", t.getCustomAttribute(KEY_1));
        assertEquals("b", t.getCustomAttribute(KEY_2));
        assertEquals("c", t.getCustomAttribute(KEY_3));
        
        t.removeCustomAttribute(KEY_2);
        assertArrayEquals(new String[] { KEY_1, KEY_3 }, t.getCustomAttributeNames());
        assertEquals("a", t.getCustomAttribute(KEY_1));
        assertNull(t.getCustomAttribute(KEY_2));
        assertEquals("c", t.getCustomAttribute(KEY_3));
    }

    @Test
    public void testFtlHeader3() throws Exception {
        Template t = new Template(null, "<#ftl attributes={"
                + "'" + KEY_1 + "': 'a', "
                + "'" + KEY_2 + "': 'b', "
                + "'" + KEY_3 + "': 'c' "
                + "}>",
                new Configuration(Configuration.VERSION_2_3_22));
        
        assertArrayEquals(new String[] { KEY_1, KEY_2, KEY_3 }, t.getCustomAttributeNames());
        assertEquals("a", t.getCustomAttribute(KEY_1));
        assertEquals("b", t.getCustomAttribute(KEY_2));
        assertEquals("c", t.getCustomAttribute(KEY_3));
        
        t.setCustomAttribute(KEY_2, null);
        assertArrayEquals(new String[] { KEY_1, KEY_2, KEY_3 }, t.getCustomAttributeNames());
        assertEquals("a", t.getCustomAttribute(KEY_1));
        assertNull(t.getCustomAttribute(KEY_2));
        assertEquals("c", t.getCustomAttribute(KEY_3));
    }
    
    @Test
    public void testFtlHeaderAndNullValue() throws Exception {
        final Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
        
        final Template t = new Template(null, "[#ftl attributes={ '" + KEY_1 + "': 'u' }]", cfg);
        assertEquals("u", t.getCustomAttribute(KEY_1));
        t.setCustomAttribute(KEY_1, null);
        assertNull(t.getCustomAttribute(KEY_1));
        t.removeCustomAttribute(KEY_1);
        assertEquals(null, t.getCustomAttribute(KEY_1));
    }

    @Test
    public void testObjectKey() throws Exception {
        Template t = new Template(null, "", new Configuration(Configuration.VERSION_2_3_22));
        assertNull(CUST_ATT_TMP_1.get(t));
        
        CUST_ATT_TMP_1.set(VALUE_1, t);
        assertSame(VALUE_1, CUST_ATT_TMP_1.get(t));
        assertEquals(0, t.getCustomAttributeNames().length);
        
        t.setCustomAttribute(KEY_2, VALUE_2);
        assertArrayEquals(new String[] { KEY_2 }, t.getCustomAttributeNames());        
        assertSame(VALUE_1, CUST_ATT_TMP_1.get(t));
        assertSame(VALUE_2, t.getCustomAttribute(KEY_2));
        
        CUST_ATT_TMP_2.set(VALUE_3, t);
        assertSame(VALUE_3, CUST_ATT_TMP_2.get(t));
        assertArrayEquals(new String[] { KEY_2 }, t.getCustomAttributeNames());        
    }

    @Test
    public void testScopes() throws Exception {
        try {
            assertNull(CUST_ATT_ENV_1.get());
            fail();
        } catch (IllegalStateException e) {
            // Expected
        }
        try {
            assertNull(CUST_ATT_CFG_1.get());
            fail();
        } catch (IllegalStateException e) {
            // Expected
        }
        
        final Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
        
        final Template t = new Template(null, "${testScopesFromTemplateStep1()}", cfg);
        Environment env = t.createProcessingEnvironment(this, NullWriter.INSTANCE);
        CUST_ATT_TMP_2.set(123, env);
        CUST_ATT_ENV_2.set(1234, env);
        CUST_ATT_CFG_2.set(12345, env);
        env.process();
    }

    @Test
    public void testScopesFallback() throws Exception {
        final Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
        
        final Template t = new Template(null, "[#ftl attributes={ '" + KEY_1 + "': 't' }]", cfg);
        Environment env = t.createProcessingEnvironment(this, NullWriter.INSTANCE);
        
        assertEquals("t", env.getCustomAttribute(KEY_1));
        assertEquals("t", t.getCustomAttribute(KEY_1));
        assertNull(cfg.getCustomAttribute(KEY_1));
        
        env.setCustomAttribute(KEY_1, "e");
        assertEquals("e", env.getCustomAttribute(KEY_1));
        assertEquals("t", t.getCustomAttribute(KEY_1));
        assertNull(cfg.getCustomAttribute(KEY_1));
        
        env.setCustomAttribute(KEY_1, null);
        assertNull(env.getCustomAttribute(KEY_1));
        assertEquals("t", t.getCustomAttribute(KEY_1));
        assertNull(cfg.getCustomAttribute(KEY_1));
        
        env.removeCustomAttribute(KEY_1);
        assertEquals("t", env.getCustomAttribute(KEY_1));
        assertEquals("t", t.getCustomAttribute(KEY_1));
        assertNull(cfg.getCustomAttribute(KEY_1));
        
        cfg.setCustomAttribute(KEY_2, "c2");
        assertEquals("c2", env.getCustomAttribute(KEY_2));
        assertEquals("c2", t.getCustomAttribute(KEY_2));
        assertEquals("c2", cfg.getCustomAttribute(KEY_2));
        
        t.setCustomAttribute(KEY_2, "t2");
        assertEquals("t2", env.getCustomAttribute(KEY_2));
        assertEquals("t2", t.getCustomAttribute(KEY_2));
        assertEquals("c2", cfg.getCustomAttribute(KEY_2));
        
        t.setCustomAttribute(KEY_2, null);
        assertNull(env.getCustomAttribute(KEY_2));
        assertNull(t.getCustomAttribute(KEY_2));
        assertEquals("c2", cfg.getCustomAttribute(KEY_2));
        
        t.removeCustomAttribute(KEY_2);
        assertEquals("c2", env.getCustomAttribute(KEY_2));
        assertEquals("c2", t.getCustomAttribute(KEY_2));
        assertEquals("c2", cfg.getCustomAttribute(KEY_2));
        
        cfg.setCustomAttribute(KEY_2, "c2+");
        assertEquals("c2+", env.getCustomAttribute(KEY_2));
        assertEquals("c2+", t.getCustomAttribute(KEY_2));
        assertEquals("c2+", cfg.getCustomAttribute(KEY_2));
    }
    
    public void testScopesFromTemplateStep1() throws Exception {
        assertNull(CUST_ATT_TMP_1.get());
        assertEquals(123, CUST_ATT_TMP_2.get());
        
        assertNull(CUST_ATT_ENV_1.get());
        assertEquals(1234, CUST_ATT_ENV_2.get());
        
        assertNull(CUST_ATT_CFG_1.get());
        assertEquals(12345, CUST_ATT_CFG_2.get());
    }
    
}
