/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.collection.maps;

import java.util.AbstractSet;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Pattern;
import net.ranides.assira.collection.iterators.IteratorUtils;
import net.ranides.assira.collection.mockup.TMaps;
import net.ranides.assira.ContractTesters;
import net.ranides.assira.generic.CompareUtils;
import net.ranides.assira.test.TMap;
import org.junit.Test;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class AIntMapTest {
    
    private final TMap<Integer, String> $map = TMaps.MAP_IS;
    
    @Test
    public void testSuite() {
        ContractTesters.runner()
            .param("map!", $map)
			.ignore(Pattern.compile(".*_HC"))
            .ignore("MapTester.basicEntrySet_Iterator_SetValue")
            .ignore("IntMapTester.basicEntrySet_Iterator_SetValue")
            .function(new int[0], array -> $map.list(array).into(new ATMap($map.comparator())))
			.run();
    }
    
    private static class ATMap extends AIntMap<String> {
        
        private final Map<Integer, String> data;

        public ATMap(Comparator<Integer> cmp) {
            data = new TreeMap<>(cmp);
        }

        @Override
        public String put(int key, String value) {
            return data.put(key, value);
        }

        @Override
        public boolean containsKey(int key) {
            return data.containsKey(key);
        }
        
        @Override
        public boolean containsValue(Object v) {
            return data.containsValue(v);
        }

        @Override
        public String get(int key) {
            return data.get(key);
        }
        
        @Override
        public void clear() {
            data.clear();
        }
        
        @Override
        public int size() {
            return data.size();
        }
        
        @Override
        public String remove(int key) {
            return data.remove(key);
        }

        @Override
        public Set<IntEntry<String>> fastEntrySet() {
            return new AbstractSet<IntEntry<String>>() {

                @Override
                public Iterator<IntEntry<String>> iterator() {
                    return IteratorUtils.map(data.entrySet().iterator(), entry -> new BasicEntry<>(entry.getKey(), entry.getValue()));
                }

                @Override
                public int size() {
                    return data.size();
                }
                
                @SuppressWarnings("unchecked")
                @Override
                public boolean remove(Object object) {
                    if(object instanceof Entry) {
                        Entry<Integer, String> entry = (Entry<Integer, String>)object;
                        return data.remove(entry.getKey(), entry.getValue());
                    }
                    return false;
                }

                @SuppressWarnings("unchecked")
                @Override
                public boolean contains(Object object) {
                    if(!(object instanceof Entry)) {
                        return false;
                    }
                    Entry<Integer, String> entry = (Entry<Integer, String>)object;
                    if(!data.containsKey(entry.getKey())) {
                        return false;
                    }
                    return CompareUtils.equals(data.get(entry.getKey()), entry.getValue());
                }
                
            };
        }

    }
    
}
