/*
 * 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 org.osgi.util.converter;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.Map;

import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class ConverterMapTest {
    private Converter converter;

    @Before
    public void setUp() {
        converter = Converters.standardConverter();
    }

    @After
    public void tearDown() {
        converter = null;
    }

    @Test
    public void testGenericMapConversion() {
        Map<Integer, String> m1 = Collections.singletonMap(42, "987654321");
        Map<String, Long> m2 = converter.convert(m1).to(new TypeReference<Map<String, Long>>(){});
        assertEquals(1, m2.size());
        assertEquals(987654321L, (long) m2.get("42"));
    }

    @Test
    public void testConvertMapToDictionary() throws Exception {
        Map<BigInteger, URL> m = new HashMap<>();
        BigInteger bi = new BigInteger("123");
        URL url = new URL("http://0.0.0.0:123");
        m.put(bi, url);

        @SuppressWarnings("unchecked")
        Dictionary<BigInteger, URL> d = converter.convert(m).to(Dictionary.class);
        assertEquals(1, d.size());
        assertSame(bi, d.keys().nextElement());
        assertSame(url, d.get(bi));
    }

    @Test
    public void testJavaBeanToMap() {
        MyBean mb = new MyBean();
        mb.setMe("You");
        mb.setF(true);
        mb.setNumbers(new int[] {3,2,1});

        @SuppressWarnings("rawtypes")
        Map m = converter.convert(mb).sourceAsBean().to(Map.class);
        assertEquals(5, m.size());
        assertEquals("You", m.get("me"));
        assertTrue((boolean) m.get("f"));
        assertFalse((boolean) m.get("enabled"));
        assertArrayEquals(new int [] {3,2,1}, (int[]) m.get("numbers"));
    }

    @Test
    public void testJavaBeanToMapCustom() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssZ");
        Date d = new Date();
        String expectedDate = sdf.format(d);

        MyBean mb = new MyBean();
        mb.setStartDate(d);
        mb.setEnabled(true);

        ConverterBuilder cb = Converters.newConverterBuilder();
        cb.rule(new Rule<Date,String>(v -> sdf.format(v)) {});
        cb.rule(new Rule<String,Date>(v -> {
            try {
                return sdf.parse(v);
            } catch (Exception ex) {
                return null;
            }
        }) {});
        Converter ca = cb.build();
        Map<String, String> m = ca.convert(mb).sourceAsBean().to(new TypeReference<Map<String, String>>(){});
        assertEquals("true", m.get("enabled"));
        assertEquals(expectedDate, m.get("startDate"));
    }

    @Test
    public void testMapToJavaBean() {
        Map<String, String> m = new HashMap<>();

        m.put("me", "Joe");
        m.put("enabled", "true");
        m.put("numbers", "42");
        m.put("s", "will disappear");
        MyBean mb = converter.convert(m).targetAsBean().to(MyBean.class);
        assertEquals("Joe", mb.getMe());
        assertTrue(mb.isEnabled());
        assertNull(mb.getF());
        assertArrayEquals(new int[] {42}, mb.getNumbers());
    }

    public void testMapToJavaBean2() {
        Map<String, String> m = new HashMap<>();

        m.put("blah", "blahblah");
        m.put("f", "true");
        MyBean mb = converter.convert(m).to(MyBean.class);
        assertNull(mb.getMe());
        assertTrue(mb.getF());
        assertFalse(mb.isEnabled());
        assertNull(mb.getNumbers());
    }

    @Test
    public void testInterfaceToMap() {
        TestInterface impl = new TestInterface() {
            @Override
            public String foo() {
                return "Chocolate!";
            }

            @Override
            public int bar() {
                return 76543;
            }

            @Override
            public int bar(String def) {
                return 0;
            }

            @Override
            public Boolean za_za() {
                return true;
            }
        };

        @SuppressWarnings("rawtypes")
        Map m = converter.convert(impl).to(Map.class);
        assertEquals(3, m.size());
        assertEquals("Chocolate!", m.get("foo"));
        assertEquals(76543, (int) m.get("bar"));
        assertEquals(true, (boolean) m.get("za.za"));
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Test
    public void testMapToInterface1() {
        Map m = new HashMap<>();
        m.put("foo", 12345);
        m.put("bar", "999");
        m.put("alt", "someval");
        m.put("za.za", true);

        TestInterface ti = converter.convert(m).to(TestInterface.class);
        assertEquals("12345", ti.foo());
        assertEquals(999, ti.bar());
        assertEquals(Boolean.TRUE, ti.za_za());
    }

    @SuppressWarnings("rawtypes")
    @Test
    public void testMapToInterface2() {
        Map m = new HashMap<>();

        TestInterface ti = converter.convert(m).to(TestInterface.class);
        try {
            ti.foo();
            fail("Should have thrown a conversion exception");
        } catch (ConversionException ce) {
        	// good
        }
        assertEquals(999, ti.bar("999"));
        try {
            assertNull(ti.za_za());
            fail("Should have thrown a conversion exception");
        } catch (ConversionException ce) {
            // good
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Test
    public void testMapToAnnotation1() {
        Map m = new HashMap<>();
        m.put("foo", 12345);
        m.put("bar", "999");
        m.put("alt", "someval");
        m.put("za.za", true);

        TestAnnotation ta = converter.convert(m).to(TestAnnotation.class);
        assertEquals("12345", ta.foo());
        assertEquals(999, ta.bar());
        assertTrue(ta.za_za());
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Test
    public void testMapToAnnotationDefaults() {
        Map m = new HashMap<>();
        m.put("alt", "someval");

        TestAnnotation ta = converter.convert(m).to(TestAnnotation.class);
        assertEquals("fooo!", ta.foo());
        assertEquals(42, ta.bar());
    }

    @Test
    public void testAnnotationMethods() {
        TestAnnotation ta = converter.convert(new HashMap<>()).to(TestAnnotation.class);
        Map<String, Object> m = converter.convert(ta).view().to(new TypeReference<Map<String, Object>>(){});
        assertEquals(3, m.size());
        assertEquals("fooo!", m.get("foo"));
        assertEquals(42, m.get("bar"));
        try {
            assertEquals(false, m.get("za.za"));
            fail("Should have thrown a conversion exception as there is no default for 'za.za'");
        } catch (ConversionException ce) {
        	// good
        }
    }

    @Test
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void testSingleElementAnnotation() {
    	class MySingleElementAnnotation implements SingleElementAnnotation {
            @Override
            public Class<? extends Annotation> annotationType() {
                return SingleElementAnnotation.class;
            }

            @Override
            public String[] value() {
                return new String[] {"hi", "there"};
            }

            @Override
            public long somethingElse() {
                return 42;
            }
    	};
    	MySingleElementAnnotation sea = new MySingleElementAnnotation();
    	Map m = converter.convert(sea).to(Map.class);
    	assertEquals(2, m.size());
    	assertArrayEquals(new String[] {"hi", "there"}, (String []) m.get("single.element.annotation"));
    	assertEquals(42L, m.get("somethingElse"));

    	m.put("somethingElse", 51.0);
    	SingleElementAnnotation sea2 = converter.convert(m).to(SingleElementAnnotation.class);
    	assertArrayEquals(new String[] {"hi", "there"}, sea2.value());
    	assertEquals(51L, sea2.somethingElse());
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Test
    public void testCopyMap() {
        Object obj = new Object();
        Map m = new HashMap<>();
        m.put("key", obj);
        Map cm = converter.convert(m).to(Map.class);
        assertNotSame(m, cm);
        assertSame(m.get("key"), cm.get("key"));
    }

    @Test
    public void testProxyObjectMethodsInterface() {
        Map<String, String> m = new HashMap<>();
        TestInterface ti = converter.convert(m).to(TestInterface.class);
        assertTrue(ti.equals(ti));
        assertFalse(ti.equals(new Object()));
        assertFalse(ti.equals(null));

        assertNotNull(ti.toString());
        assertTrue(ti.hashCode() != 0);
    }

    @Test
    public void testProxyObjectMethodsAnnotation() {
        Map<String, String> m = new HashMap<>();
        TestAnnotation ta = converter.convert(m).to(TestAnnotation.class);
        assertTrue(ta.equals(ta));
    }

    @Test
    public void testCaseInsensitiveKeysAnnotation() {
        Map<String, Object> m = new HashMap<>();
        m.put("FOO", "Bleh");
        m.put("baR", 21);
        m.put("za.za", true);

        TestInterface ti = converter.convert(m).keysIgnoreCase().to(TestInterface.class);
        assertEquals("Bleh", ti.foo());
        assertEquals(21, ti.bar("42"));
        assertTrue(ti.za_za());
    }

    @Test
    public void testCaseSensitiveKeysAnnotation() {
        Map<String, Object> m = new HashMap<>();
        m.put("FOO", "Bleh");
        m.put("baR", 21);
        m.put("za.za", true);

        TestInterface ti = converter.convert(m).to(TestInterface.class);
        try {
            ti.foo();
            fail("Should have thrown a conversion exception as 'foo' was not set");
        } catch (ConversionException ce) {
            // good
        }
        assertEquals(42, ti.bar("42"));
        assertTrue(ti.za_za());
    }

    @Test
    public void testCaseInsensitiveDTO() {
        Dictionary<String, String> d = new Hashtable<>();
        d.put("COUNT", "one");
        d.put("PinG", "Piiiiiiing!");
        d.put("pong", "999");

        MyDTO dto = converter.convert(d).keysIgnoreCase().to(MyDTO.class);
        assertEquals(MyDTO.Count.ONE, dto.count);
        assertEquals("Piiiiiiing!", dto.ping);
        assertEquals(999L, dto.pong);
    }

    @Test
    public void testCaseSensitiveDTO() {
        Dictionary<String, String> d = new Hashtable<>();
        d.put("COUNT", "one");
        d.put("PinG", "Piiiiiiing!");
        d.put("pong", "999");

        MyDTO dto = converter.convert(d).to(MyDTO.class);
        assertNull(dto.count);
        assertNull(dto.ping);
        assertEquals(999L, dto.pong);
    }

    @Test
    public void testRemovePasswords() {
        Map<String, Object> m = new LinkedHashMap<>();
        m.put("foo", "bar");
        m.put("password", "secret");

        Converter c = converter.newConverterBuilder().
            rule(new Rule<Map<String,Object>,String>(v -> {
                Map<String, Object> cm = new LinkedHashMap<>(v);

                for (Map.Entry<String, Object> entry : cm.entrySet()) {
                    if (entry.getKey().contains("password"))
                        entry.setValue("xxx");
                }
                return cm.toString();
            }) {}).
            build();
        assertEquals("{foo=bar, password=xxx}", c.convert(m).to(String.class));
        assertEquals("Original should not be modified",
                "{foo=bar, password=secret}", m.toString());
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Test @Ignore
    public void testAnnotationDefaultMaterializer() throws Exception {
        Map<String, Object> vals = new HashMap<>();
        vals.put("bar", 99L);
        vals.put("tar", true);
        vals.put("za.za", false);

        Class<?> ta1cls = getClass().getClassLoader().loadClass(getClass().getPackage().getName() + ".sub1.TestAnn1");
        Object ta = converter.convert(vals).to(ta1cls);
        Map vals2 = converter.convert(ta).to(Map.class);
        vals2.putAll(vals);
        Class<?> ta2cls = getClass().getClassLoader().loadClass(getClass().getPackage().getName() + ".sub2.TestAnn2");
        Object ta2 = converter.convert(vals2).to(ta2cls);

        Method m1 = ta2cls.getDeclaredMethod("foo");
        m1.setAccessible(true);
        assertEquals("fooo!", m1.invoke(ta2));

        Method m2 = ta2cls.getDeclaredMethod("bar");
        m2.setAccessible(true);
        assertEquals(99, m2.invoke(ta2));

        Method m3 = ta2cls.getDeclaredMethod("tar");
        m3.setAccessible(true);
        assertEquals(true, m3.invoke(ta2));
    }

    @Test
    public void testMapEntry() {
        Map<String, Boolean> m1 = Collections.singletonMap("Hi", Boolean.TRUE);
        Map.Entry<String, Boolean> e1 = getMapEntry(m1);

        assertTrue(converter.convert(e1).to(Boolean.class));
        assertTrue(converter.convert(e1).to(boolean.class));
        assertEquals("Hi", converter.convert(e1).to(String.class));

    }

    @Test
    public void testMapEntry1() {
        Map<Long, String> m1 = Collections.singletonMap(17L, "18");
        Map.Entry<Long, String> e1 = getMapEntry(m1);

        assertEquals(17L, converter.convert(e1).to(Number.class));
        assertEquals("18", converter.convert(e1).to(String.class));
        assertEquals("18", converter.convert(e1).to(Bar.class).value);
    }

    @Test
    public void testMapEntry2() {
        Map<String, Short> m1 = Collections.singletonMap("123", Short.valueOf((short) 567));
        Map.Entry<String, Short> e1 = getMapEntry(m1);

        assertEquals(Integer.valueOf(123), converter.convert(e1).to(Integer.class));
    }

    @Test
    public void testMapEntry3() {
        Map<Long,Long> l1 = Collections.singletonMap(9L, 10L);
        Map.Entry<Long, Long> e1 = getMapEntry(l1);

        assertEquals("Should take the key if key and value are equally suitable",
                9L, (long) converter.convert(e1).to(long.class));
    }

    @Test
    public void testMapEntry4() {
        Map<Foo, Foo> m1 = Collections.singletonMap(new Foo(111), new Foo(999));
        Map.Entry<Foo, Foo> e1 = getMapEntry(m1);

        assertEquals("111", converter.convert(e1).to(Bar.class).value);
    }

    @Test
    public void testDictionaryToAnnotation() {
        Dictionary<String, Object> dict = new TestDictionary<>();
        dict.put("foo", "hello");
        TestAnnotation ta = converter.convert(dict).to(TestAnnotation.class);
        assertEquals("hello", ta.foo());
    }

    @Test
    public void testDictionaryToMap() {
        Dictionary<String, Object> dict = new TestDictionary<>();
        dict.put("foo", "hello");
        @SuppressWarnings("rawtypes")
        Map m = converter.convert(dict).to(Map.class);
        assertEquals("hello", m.get("foo"));
    }

    @Test
    public void testInterfaceWithGetProperties() {
        TestInterfaceWithGetProperties tiwgp = new TestInterfaceWithGetProperties() {
            @Override
            public int blah() {
                return 99;
            }

            @Override
            public Dictionary<String, Object> getProperties() {
                Dictionary<String, Object> d = new TestDictionary<>();
                d.put("hi", "ha");
                d.put("ho", "ho");
                return d;
            }
        };

        @SuppressWarnings("rawtypes")
        Map m = converter.convert(tiwgp).to(Map.class);
        assertEquals(2, m.size());
        assertEquals("ha", m.get("hi"));
        assertEquals("ho", m.get("ho"));
    }

    @Test
    public void testInterfaceWithGetPropertiesCopied() {
        TestInterfaceWithGetProperties tiwgp = new TestInterfaceWithGetProperties() {
            @Override
            public int blah() {
                return 99;
            }

            @Override
            public Dictionary<String, Object> getProperties() {
                Dictionary<String, Object> d = new TestDictionary<>();
                d.put("hi", "ha");
                d.put("ho", "ho");
                return d;
            }
        };

        @SuppressWarnings("rawtypes")
        Map m = converter.convert(tiwgp).to(Map.class);
        assertEquals(2, m.size());
        assertEquals("ha", m.get("hi"));
        assertEquals("ho", m.get("ho"));
    }

    @Test
    public void testMapWithKeywords() {
        Map<String, Object> m = new HashMap<>();
        m.put("new", "123");
        m.put("continue", 987l);

        MyDTOWithKeyWords dto = converter.convert(m).to(MyDTOWithKeyWords.class);
        assertEquals(123l, dto.$new);
        assertEquals("987", dto.$continue);

        Map<String, Object> m2 = converter.convert(dto).to(new TypeReference<Map<String, Object>>() {});
        assertEquals(2, m2.size());
        assertEquals(123l, m2.get("new"));
        assertEquals("987", m2.get("continue"));
    }

    @Test
    public void testSingleElementAnnotationPrefix() {
        final Converter converter = Converters.standardConverter();
        final TestValue testValue = converter.convert(Collections.singletonMap("my.prefix.test.value", true)).to(TestValue.class);
        assertTrue(testValue.value());
    }
    
    private <K,V> Map.Entry<K,V> getMapEntry(Map<K,V> map) {
        assertEquals("This method assumes a map of size 1", 1, map.size());
        return map.entrySet().iterator().next();
    }

    interface TestInterface {
        String foo();
        int bar();
        int bar(String def);
        Boolean za_za();
    }

    interface TestInterfaceWithGetProperties {
        int blah();
        Dictionary<String, Object> getProperties();
    }

    @interface TestAnnotation {
        String foo() default "fooo!";
        int bar() default 42;
        boolean za_za();
    }

    @interface SingleElementAnnotation {
    	String[] value();
    	long somethingElse() default -87;
    }

    @interface TestValue {
        static final String PREFIX_ = "my.prefix.";

        boolean value();
    }
    
    private static class Foo {
        private final int value;

        Foo(int v) {
            value = v;
        }

        @Override
        public String toString() {
            return "" + value;
        }
    }

    public static class Bar {
        final String value;
        public Bar(String v) {
            value = v;
        }
    }

    public static class MyDTOWithKeyWords {
        public long $new;
        public String $continue;
    }
}
