/*******************************************************************************
 * 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.apache.ofbiz.base.util.collections.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.ofbiz.base.test.GenericTestCaseBase;
import org.apache.ofbiz.base.util.collections.GenericMap;
import org.apache.ofbiz.base.util.collections.GenericMapEntry;
import org.apache.ofbiz.base.util.collections.IteratorWrapper;

public class GenericMapTest extends GenericTestCaseBase {
    @SuppressWarnings("serial")
    public static class TestGenericMap<K, V> extends GenericMap<K, V> {
        private static final String[] countNames = {
            "clearInternal",
            "containsKey",
            "get-true",
            "get-false",
            "isEmpty",
            "iterator-true",
            "iterator-false",
            "putInternal",
            "putAllIterator",
            "removeInternal-true",
            "removeInternal-false",
            "size",
        };
        protected final Map<String, Integer> counts = new HashMap<String, Integer>();
        protected final Map<K, V> proxyMap;

        protected TestGenericMap() {
            this(null);
        }

        protected TestGenericMap(Map<K, V> srcMap) {
            for (String countName: countNames) {
                counts.put(countName, 0);
            }
            if (srcMap != null) {
                proxyMap = new HashMap<K, V>(srcMap);
            } else {
                proxyMap = new HashMap<K, V>();
            }
        }

        private void incrementCallCount(String name) {
            counts.put(name, counts.get(name) + 1);
        }

        public List<Integer> getCounts() {
            List<Integer> result = new ArrayList<Integer>();
            for (String countName: countNames) {
                result.add(counts.get(countName));
            }
            return result;
        }

        @Override
        protected void clearInternal() {
            incrementCallCount("clearInternal");
            proxyMap.clear();
        }

        public boolean containsKey(Object key) {
            incrementCallCount("containsKey");
            return proxyMap.containsKey(key);
        }

        @Override
        protected V get(Object key, boolean noteAccess) {
            incrementCallCount("get-" + noteAccess);
            return proxyMap.get(key);
        }

        public boolean isEmpty() {
            incrementCallCount("isEmpty");
            return proxyMap.isEmpty();
        }

        @Override
        protected Iterator<Map.Entry<K, V>> iterator(final boolean noteAccess) {
            incrementCallCount("iterator-" + noteAccess);
            return new IteratorWrapper<Map.Entry<K, V>, Map.Entry<K, V>>(proxyMap.entrySet().iterator()) {
                @Override
                protected Map.Entry<K, V> convert(Map.Entry<K, V> src) {
                    return new GenericMapEntry<K, V>(TestGenericMap.this, src.getKey(), noteAccess);
                }
                @Override
                protected void noteRemoval(Map.Entry<K, V> dest, Map.Entry<K, V> src) {
                }
            };
        }

        public V put(K key, V value) {
            incrementCallCount("putInternal");
            if (!proxyMap.containsKey(key)) incrementModCount();
            return proxyMap.put(key, value);
        }

        @Override
        protected <KE extends K, VE extends V> void putAllIterator(Iterator<Map.Entry<KE, VE>> it) {
            incrementCallCount("putAllIterator");
            while (it.hasNext()) {
                Map.Entry<KE, VE> entry = it.next();
                proxyMap.put(entry.getKey(), entry.getValue());
            }
        }

        @Override
        protected V removeInternal(Object key, boolean incrementModCount) {
            incrementCallCount("removeInternal-" + incrementModCount);
            if (!proxyMap.containsKey(key)) return null;
            if (incrementModCount) incrementModCount();
            return proxyMap.remove(key);
        }

        public int size() {
            incrementCallCount("size");
            return proxyMap.size();
        }
    }

    public GenericMapTest(String name) {
        super(name);
    }

    public void testFoo() throws Exception {
        TestGenericMap<String, Integer> map = new TestGenericMap<String, Integer>();
        map.put("a", 0); System.err.println("put a\t\tcounts=" + map.getCounts() + ", modCount=" + map.getModCount());
        assertEquals("get a", Integer.valueOf(0), map.get("a"));
        map.put("b", 1); System.err.println("put b\t\tcounts=" + map.getCounts() + ", modCount=" + map.getModCount());
        assertEquals("get b", Integer.valueOf(1), map.get("b"));
        map.put("c", 2); System.err.println("put c\t\tcounts=" + map.getCounts() + ", modCount=" + map.getModCount());
        assertEquals("get c", Integer.valueOf(2), map.get("c"));
        map.put("d", 3); System.err.println("put d\t\tcounts=" + map.getCounts() + ", modCount=" + map.getModCount());
        assertEquals("get d", Integer.valueOf(3), map.get("d"));
        map.put("c", 22); System.err.println("put c-2\t\tcounts=" + map.getCounts() + ", modCount=" + map.getModCount());
        assertEquals("get c-2", Integer.valueOf(22), map.get("c"));
        map.remove("b"); System.err.println("remove b\tcounts=" + map.getCounts() + ", modCount=" + map.getModCount());
        assertNull("null b", map.get("b"));
        map.remove("aaa"); System.err.println("remove aaa\tcounts=" + map.getCounts() + ", modCount=" + map.getModCount());
        System.err.println("map=" + map);
        System.err.println("counts=" + map.getCounts() + ", modCount=" + map.getModCount());
        // this seems to call size()
        new HashMap<String, Integer>(map);
        System.err.println("counts=" + map.getCounts() + ", modCount=" + map.getModCount());
    }

}
