// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 1996-2016, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */
package com.ibm.icu.dev.test.translit;

import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import com.ibm.icu.dev.test.TestBoilerplate;
import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.dev.util.UnicodeMap;
import com.ibm.icu.dev.util.UnicodeMap.EntryRange;
import com.ibm.icu.dev.util.UnicodeMapIterator;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UProperty;
import com.ibm.icu.text.UTF16;
import com.ibm.icu.text.UnicodeSet;

/**
 * @test
 * @summary General test of UnicodeSet
 */
@RunWith(JUnit4.class)
public class UnicodeMapTest extends TestFmwk {

    static final int MODIFY_TEST_LIMIT = 32;
    static final int MODIFY_TEST_ITERATIONS = 100000;

    @Test
    public void TestIterations() {
        UnicodeMap<Double> foo = new UnicodeMap();
        checkToString(foo, "");
        foo.put(3, 6d).put(5, 10d);
        checkToString(foo, "0003=6.0\n0005=10.0\n");
        foo.put(0x10FFFF, 666d);
        checkToString(foo, "0003=6.0\n0005=10.0\n10FFFF=666.0\n");
        foo.put("neg", -555d);
        checkToString(foo, "0003=6.0\n0005=10.0\n10FFFF=666.0\n006E,0065,0067=-555.0\n");

        double i = 0;
        for (EntryRange<Double> entryRange : foo.entryRanges()) {
            i += entryRange.value;
        }
        assertEquals("EntryRange<T>", 127d, i);
    }

    public void checkToString(UnicodeMap<Double> foo, String expected) {
        assertEquals("EntryRange<T>", expected, CollectionUtilities.join(foo.entryRanges(), "\n") + (foo.size() == 0 ? "" : "\n"));
        assertEquals("EntryRange<T>", expected, foo.toString());
    }

    @Test
    public void TestRemove() {
        UnicodeMap<Double> foo = new UnicodeMap()
        .putAll(0x20, 0x29, -2d)
        .put("abc", 3d)
        .put("xy", 2d)
        .put("mark", 4d)
        .freeze();
        UnicodeMap<Double> fii = new UnicodeMap()
        .putAll(0x21, 0x25, -2d)
        .putAll(0x26, 0x28, -3d)
        .put("abc", 3d)
        .put("mark", 999d)
        .freeze();

        UnicodeMap<Double> afterFiiRemoval = new UnicodeMap()
        .put(0x20, -2d)
        .putAll(0x26, 0x29, -2d)
        .put("xy", 2d)
        .put("mark", 4d)
        .freeze();

        UnicodeMap<Double> afterFiiRetained = new UnicodeMap()
        .putAll(0x21, 0x25, -2d)
        .put("abc", 3d)
        .freeze();

        UnicodeMap<Double> test = new UnicodeMap<Double>().putAll(foo)
                .removeAll(fii);
        assertEquals("removeAll", afterFiiRemoval, test);

        test = new UnicodeMap<Double>().putAll(foo)
                .retainAll(fii);
        assertEquals("retainAll", afterFiiRetained, test);
    }

    @Test
    public void TestAMonkey() {
        SortedMap<String,Integer> stayWithMe = new TreeMap<String,Integer>(OneFirstComparator);

        UnicodeMap<Integer> me = new UnicodeMap<Integer>().putAll(stayWithMe);
        // check one special case, removal near end
        me.putAll(0x10FFFE, 0x10FFFF, 666);
        me.remove(0x10FFFF);

        int iterations = 100000;
        SortedMap<String,Integer> test = new TreeMap();

        Random rand = new Random(0);
        String other;
        Integer value;
        // try modifications
        for (int i = 0; i < iterations ; ++i) {
            switch(rand.nextInt(20)) {
            case 0:
                logln("clear");
                stayWithMe.clear();
                me.clear();
                break;
            case 1:
                fillRandomMap(rand, 5, test);
                logln("putAll\t" + test);
                stayWithMe.putAll(test);
                me.putAll(test);
                break;
            case 2: case 3: case 4: case 5: case 6: case 7: case 8:
                other = getRandomKey(rand);
                //                if (other.equals("\uDBFF\uDFFF") && me.containsKey(0x10FFFF) && me.get(0x10FFFF).equals(me.get(0x10FFFE))) {
                //                    System.out.println("Remove\t" + other + "\n" + me);
                //                }
                logln("remove\t" + other);
                stayWithMe.remove(other);
                try {
                    me.remove(other);
                } catch (IllegalArgumentException e) {
                    errln("remove\t" + other + "\tfailed: " + e.getMessage() + "\n" + me);
                    me.clear();
                    stayWithMe.clear();
                }
                break;
            default:
                other = getRandomKey(rand);
                value = rand.nextInt(50)+50;
                logln("put\t" + other + " = " + value);
                stayWithMe.put(other, value);
                me.put(other,value);
                break;
            }
            checkEquals(me, stayWithMe);
        }
    }

    /**
     * @param rand
     * @param nextInt
     * @param test
     * @return
     */
    private SortedMap<String, Integer> fillRandomMap(Random rand, int max, SortedMap<String, Integer> test) {
        test.clear();
        max = rand.nextInt(max);
        for (int i = 0; i < max; ++i) {
            test.put(getRandomKey(rand), rand.nextInt(50)+50);
        }
        return test;
    }

    Set temp = new HashSet();
    /**
     * @param me
     * @param stayWithMe
     */
    private void checkEquals(UnicodeMap<Integer> me, SortedMap<String, Integer> stayWithMe) {
        temp.clear();
        for (Entry<String, Integer> e : me.entrySet()) {
            temp.add(e);
        }
        Set<Entry<String, Integer>> entrySet = stayWithMe.entrySet();
        if (!entrySet.equals(temp)) {
            logln(me.entrySet().toString());
            logln(me.toString());
            assertEquals("are in parallel", entrySet, temp);
            // we failed. Reset and start again
            entrySet.clear();
            temp.clear();
            return;
        }
        for (String key : stayWithMe.keySet()) {
            assertEquals("containsKey", stayWithMe.containsKey(key), me.containsKey(key));
            Integer value = stayWithMe.get(key);
            assertEquals("get", value, me.get(key));
            assertEquals("containsValue", stayWithMe.containsValue(value), me.containsValue(value));
            int cp = UnicodeSet.getSingleCodePoint(key);
            if (cp != Integer.MAX_VALUE) {
                assertEquals("get", value, me.get(cp));
            }
        }
        Set<String> nonCodePointStrings = stayWithMe.tailMap("").keySet();
        if (nonCodePointStrings.size() == 0) nonCodePointStrings = null; // for parallel api
        assertEquals("getNonRangeStrings", nonCodePointStrings, me.getNonRangeStrings());

        TreeSet<Integer> values = new TreeSet<Integer>(stayWithMe.values());
        TreeSet<Integer> myValues = new TreeSet<Integer>(me.values());
        assertEquals("values", myValues, values);

        for (String key : stayWithMe.keySet()) {
            assertEquals("containsKey", stayWithMe.containsKey(key), me.containsKey(key));
        }
    }

    static Comparator<String> OneFirstComparator = new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            int cp1 = UnicodeSet.getSingleCodePoint(o1);
            int cp2 = UnicodeSet.getSingleCodePoint(o2);
            int result = cp1 - cp2;
            if (result != 0) {
                return result;
            }
            if (cp1 == Integer.MAX_VALUE) {
                return o1.compareTo(o2);
            }
            return 0;
        }

    };

    /**
     * @param rand
     * @param others
     * @return
     */
    private String getRandomKey(Random rand) {
        int r = rand.nextInt(30);
        if (r == 0) {
            return UTF16.valueOf(r);
        } else if (r < 10) {
            return UTF16.valueOf('A'-1+r);
        } else if (r < 20) {
            return UTF16.valueOf(0x10FFFF - (r-10));
            //        } else if (r == 20) {
            //            return "";
        }
        return "a" + UTF16.valueOf(r + 'a'-1);
    }

    @Test
    public void TestModify() {
        Random random = new Random(0);
        UnicodeMap unicodeMap = new UnicodeMap();
        HashMap hashMap = new HashMap();
        String[] values = {null, "the", "quick", "brown", "fox"};
        for (int count = 1; count <= MODIFY_TEST_ITERATIONS; ++count) {
            String value = values[random.nextInt(values.length)];
            int start = random.nextInt(MODIFY_TEST_LIMIT); // test limited range
            int end = random.nextInt(MODIFY_TEST_LIMIT);
            if (start > end) {
                int temp = start;
                start = end;
                end = temp;
            }
            int modCount = count & 0xFF;
            if (modCount == 0 && isVerbose()) {
                logln("***"+count);
                logln(unicodeMap.toString());
            }
            unicodeMap.putAll(start, end, value);
            if (modCount == 1 && isVerbose()) {
                logln(">>>\t" + Utility.hex(start) + ".." + Utility.hex(end) + "\t" + value);
                logln(unicodeMap.toString());
            }
            for (int i = start; i <= end; ++i) {
                hashMap.put(new Integer(i), value);
            }
            if (!hasSameValues(unicodeMap, hashMap)) {
                errln("Failed at " + count);
            }
        }
    }

    private boolean hasSameValues(UnicodeMap unicodeMap, HashMap hashMap) {
        for (int i = 0; i < MODIFY_TEST_LIMIT; ++i) {
            Object unicodeMapValue = unicodeMap.getValue(i);
            Object hashMapValue = hashMap.get(new Integer(i));
            if (unicodeMapValue != hashMapValue) {
                return false;
            }
        }
        return true;
    }

    @Test
    public void TestCloneAsThawed11721 () {
        UnicodeMap<Integer> test = new UnicodeMap().put("abc", 3).freeze();
        UnicodeMap<Integer> copy = test.cloneAsThawed();
        copy.put("def", 4);
        assertEquals("original-abc", (Integer) 3, test.get("abc"));
        assertNull("original-def", test.get("def"));
        assertEquals("copy-def", (Integer) 4, copy.get("def"));
    }

    private static final int LIMIT = 0x15; // limit to make testing more realistic in terms of collisions
    private static final int ITERATIONS = 1000000;
    private static final boolean SHOW_PROGRESS = false;
    private static final boolean DEBUG = false;

    SortedSet<String> log = new TreeSet<String>();
    static String[] TEST_VALUES = {"A", "B", "C", "D", "E", "F"};
    static Random random = new Random(12345);

    @Test
    public void TestUnicodeMapRandom() {
        // do random change to both, then compare
        random.setSeed(12345); // reproducible results
        logln("Comparing against HashMap");
        UnicodeMap<String> map1 = new UnicodeMap();
        Map<Integer, String> map2 = new HashMap<Integer, String>();
        for (int counter = 0; counter < ITERATIONS; ++counter) {
            int start = random.nextInt(LIMIT);
            String value = TEST_VALUES[random.nextInt(TEST_VALUES.length)];
            String logline = Utility.hex(start) + "\t" + value;
            if (SHOW_PROGRESS) logln(counter + "\t" + logline);
            log.add(logline);
            if (DEBUG && counter == 144) {
                System.out.println(" debug");
            }
            map1.put(start, value);
            map2.put(start, value);
            check(map1, map2, counter);
        }
        checkNext(map1, map2, LIMIT);
    }

    private static final int propEnum = UProperty.GENERAL_CATEGORY;

    @Test
    public void TestUnicodeMapGeneralCategory() {
        logln("Setting General Category");
        UnicodeMap<String> map1 = new UnicodeMap();
        Map<Integer, String> map2 = new HashMap<Integer, String>();
        //Map<Integer, String> map3 = new TreeMap<Integer, String>();
        map1 = new UnicodeMap<String>();
        map2 = new TreeMap<Integer,String>();
        for (int cp = 0;;) {
              int enumValue = UCharacter.getIntPropertyValue(cp, propEnum);
              //if (enumValue <= 0) continue; // for smaller set
              String value = UCharacter.getPropertyValueName(propEnum,enumValue, UProperty.NameChoice.LONG);
              map1.put(cp, value);
              map2.put(cp, value);
              cp++;
              // Unicode is huge, skip over large parts of it.
              if (cp == 0x08FF) {           // General Scripts Area.
                  cp = 0xD700;              // Hangul Syllables Area.
              } else if (cp == 0x100FF) {   // General Scripts Area.
                  cp = 0x1F000;             // Symbols Area.
              } else if (cp == 0x200FF) {   // CJK Unified Ideographs Extensions.
                  cp = 0x10FF00;            // Supplementary Private Use Area-B.
              } else if (cp == 0x10FFFF) {  // The end of Unicode.
                  break;
              }
        }
        checkNext(map1, map2, Integer.MAX_VALUE);

        logln("Comparing General Category");
        check(map1, map2, -1);
        logln("Comparing Values");
        Set<String> values1 = map1.getAvailableValues(new TreeSet<String>());
        Set<String> values2 = new TreeSet<String>(map2.values());
        if (!TestBoilerplate.verifySetsIdentical(this, values1, values2)) {
            throw new IllegalArgumentException("Halting");
        }
        logln("Comparing Sets");
        for (Iterator<String> it = values1.iterator(); it.hasNext();) {
            String value = it.next();
            logln(value == null ? "null" : value);
            UnicodeSet set1 = map1.keySet(value);
            UnicodeSet set2 = TestBoilerplate.getSet(map2, value);
            if (!TestBoilerplate.verifySetsIdentical(this, set1, set2)) {
                throw new IllegalArgumentException("Halting");
            }
        }
    }

    @Test
    public void TestAUnicodeMap2() {
        UnicodeMap foo = new UnicodeMap();
        @SuppressWarnings("unused")
        int hash = foo.hashCode(); // make sure doesn't NPE
        @SuppressWarnings("unused")
        Set fii = foo.stringKeys(); // make sure doesn't NPE
    }

    @Test
    public void TestAUnicodeMapInverse() {
        UnicodeMap<Character> foo1 = new UnicodeMap<Character>()
                .putAll('a', 'z', 'b')
                .put("ab", 'c')
                .put('x', 'b')
                .put("xy", 'c')
                ;
        Map<Character, UnicodeSet> target = new HashMap<Character, UnicodeSet>();
        foo1.addInverseTo(target);
        UnicodeMap<Character> reverse = new UnicodeMap().putAllInverse(target);
        assertEquals("", foo1, reverse);
    }

    private void checkNext(UnicodeMap<String> map1, Map<Integer,String> map2, int limit) {
        logln("Comparing nextRange");
        Map localMap = new TreeMap();
        UnicodeMapIterator<String> mi = new UnicodeMapIterator<String>(map1);
        while (mi.nextRange()) {
            logln(Utility.hex(mi.codepoint) + ".." + Utility.hex(mi.codepointEnd) + " => " + mi.value);
            for (int i = mi.codepoint; i <= mi.codepointEnd; ++i) {
                //if (i >= limit) continue;
                localMap.put(i, mi.value);
            }
        }
        checkMap(map2, localMap);

        logln("Comparing next");
        mi.reset();
        localMap = new TreeMap();
//        String lastValue = null;
        while (mi.next()) {
//            if (!UnicodeMap.areEqual(lastValue, mi.value)) {
//                // System.out.println("Change: " + Utility.hex(mi.codepoint) + " => " + mi.value);
//                lastValue = mi.value;
//            }
            //if (mi.codepoint >= limit) continue;
            localMap.put(mi.codepoint, mi.value);
        }
        checkMap(map2, localMap);
    }

    public void check(UnicodeMap<String> map1, Map<Integer,String> map2, int counter) {
        for (int i = 0; i < LIMIT; ++i) {
            String value1 = map1.getValue(i);
            String value2 = map2.get(i);
            if (!UnicodeMap.areEqual(value1, value2)) {
                errln(counter + " Difference at " + Utility.hex(i)
                     + "\t UnicodeMap: " + value1
                     + "\t HashMap: " + value2);
                errln("UnicodeMap: " + map1);
                errln("Log: " + TestBoilerplate.show(log));
                errln("HashMap: " + TestBoilerplate.show(map2));
            }
        }
    }

    void checkMap(Map m1, Map m2) {
        if (m1.equals(m2)) return;
        StringBuilder buffer = new StringBuilder();
        Set m1entries = m1.entrySet();
        Set m2entries = m2.entrySet();
        getEntries("\r\nIn First, and not Second", m1entries, m2entries, buffer, 20);
        getEntries("\r\nIn Second, and not First", m2entries, m1entries, buffer, 20);
        errln(buffer.toString());
    }

    static Comparator<Map.Entry<Integer, String>> ENTRY_COMPARATOR = new Comparator<Map.Entry<Integer, String>>() {
        @Override
        public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
            if (o1 == o2) return 0;
            if (o1 == null) return -1;
            if (o2 == null) return 1;
            Map.Entry<Integer, String> a = o1;
            Map.Entry<Integer, String> b = o2;
            int result = compare2(a.getKey(), b.getKey());
            if (result != 0) return result;
            return compare2(a.getValue(), b.getValue());
        }
        private <T extends Comparable> int compare2(T o1, T o2) {
            if (o1 == o2) return 0;
            if (o1 == null) return -1;
            if (o2 == null) return 1;
            return o1.compareTo(o2);
        }
    };

    private void getEntries(String title, Set<Map.Entry<Integer,String>> m1entries, Set<Map.Entry<Integer, String>> m2entries, StringBuilder buffer, int limit) {
        Set<Map.Entry<Integer, String>> m1_m2 = new TreeSet<Map.Entry<Integer, String>>(ENTRY_COMPARATOR);
        m1_m2.addAll(m1entries);
        m1_m2.removeAll(m2entries);
        buffer.append(title + ": " + m1_m2.size() + "\r\n");
        for (Entry<Integer, String> entry : m1_m2) {
            if (limit-- < 0) return;
            buffer.append(entry.getKey()).append(" => ")
             .append(entry.getValue()).append("\r\n");
        }
    }
}
