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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

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

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.dev.test.util.TrieMap.Style;
import com.ibm.icu.dev.util.Timer;
import com.ibm.icu.impl.Row;
import com.ibm.icu.impl.Row.R3;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UScript;
import com.ibm.icu.text.DecimalFormat;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.util.StringTrieBuilder.Option;
import com.ibm.icu.util.ULocale;

@RunWith(JUnit4.class)
public class TrieMapTest extends TestFmwk {
    static final boolean SHORT = false;
    static final boolean HACK_TO_MAKE_TESTS_PASS = false;
    static final int MASK = 0x3;

    private Map<String, Integer> unicodeTestMap = new HashMap<String, Integer>();
    private boolean useSmallList = true;

    private static Timer t = new Timer();
    private static DecimalFormat nf = t.getNumberFormat();
    private static DecimalFormat pf = t.getPercentFormat();
    {
        pf.setMaximumFractionDigits(0);
    }

    @Before
    public void init() throws Exception {
        if (unicodeTestMap.size() == 0) {
            if (TestFmwk.getExhaustiveness() < 5) {
                logln("\tShort version, timing for 1s:\t to get more accurate figures and test for reasonable times, use -e5 or more");
                t.setTimingPeriod(1*Timer.SECONDS);
            } else {
                int seconds = TestFmwk.getExhaustiveness();
                logln("\tExhaustive version, timing for " + seconds + "s");
                t.setTimingPeriod(seconds*Timer.SECONDS);
                useSmallList = false;
            }

            int i = 0;
            UnicodeSet testSet = new UnicodeSet("[[:^C:]-[:sc=han:]]");
            for (String s : testSet) {
                int codePoint = s.codePointAt(0);
                String extendedName = UCharacter.getExtendedName(codePoint);
                if (!unicodeTestMap.containsKey(extendedName)) {
                    unicodeTestMap.put(extendedName, i++);
                }
                if (i > 500 && useSmallList) break;
            }
            ULocale[] locales = useSmallList ? new ULocale[] {new ULocale("zh"), new ULocale("el")} : ULocale.getAvailableLocales();
            for (ULocale locale : locales) {
                if (locale.getDisplayCountry().length() != 0) {
                    continue;
                }
                String localeName;
                for (String languageCode : ULocale.getISOLanguages()) {
                    localeName = ULocale.getDisplayName(languageCode, locale);
                    if (!localeName.equals(languageCode)) {
                        if (!unicodeTestMap.containsKey(localeName)) {
                            unicodeTestMap.put(localeName, MASK & i++);
                        }
                        if (SHORT) break;
                    }
                }
                for (String countryCode : ULocale.getISOCountries()) {
                    localeName = ULocale.getDisplayCountry("und-" + countryCode, locale);
                    if (!localeName.equals(countryCode)) {
                        if (!unicodeTestMap.containsKey(localeName)) {
                            unicodeTestMap.put(localeName, MASK & i++);
                        }
                        if (SHORT) break;
                    }
                }
            }
            int charCount = 0;
            for (String key : unicodeTestMap.keySet()) {
                charCount += key.length();
            }
            logln("\tTest Data Elements:\t\t\t" + nf.format(unicodeTestMap.size()));
            logln("\tTotal chars:\t\t\t" + nf.format(charCount));
        }
    }

    @Ignore
    @Test
    public void TestByteConversion() {
        byte bytes[] = new byte[200];
        for (Entry<String, Integer> entry : unicodeTestMap.entrySet()) {
            String source = entry.getKey();
            int limit = TrieMap.ByteConverter.getBytes(source, bytes, 0);
            //logln(source + "\t=> " + Utility.hex(source, " ") + "\t=> " + Utility.hex(bytes, 0, limit, " "));
            String recovered = TrieMap.ByteConverter.getChars(bytes, 0, limit);
            if (!source.equals(recovered)) {
                assertEquals("Char/Byte Conversion", source, recovered);
            }
        }
    }

    @Ignore
    @Test
    public void TestGet() {
        checkGet(unicodeTestMap, TrieMap.Style.BYTES);
        checkGet(unicodeTestMap, TrieMap.Style.CHARS);
    }

    private void checkGet(Map<String, Integer> testmap, TrieMap.Style style) {
        if (testmap.size() == 0) {
            return;
        }
        TrieMap<Integer> trieMap = TrieMap.Builder.with(style, Option.SMALL, testmap).build();
        //logln(trieMap.toString());
        for (Entry<String, Integer> entry : testmap.entrySet()) {
            Integer value = entry.getValue();
            String key = entry.getKey();
            Integer foundValue = trieMap.get(key);
            if (!value.equals(foundValue)) {
                // TODO fix this
                if (!HACK_TO_MAKE_TESTS_PASS || 39497 != value) {
                    assertEquals(style + "\tGet of '" + key + "' = {" + Utility.hex(key) + "}", value, foundValue);
                }
            }
        }
    }

    @Ignore
    @Test
    public void TestTimeIteration() {
        long comparisonTime = timeIteration(unicodeTestMap, 0, null, 0);
        timeIteration(unicodeTestMap, comparisonTime, null, 0);
        timeIteration(unicodeTestMap, comparisonTime, Style.BYTES, 5);
        timeIteration(unicodeTestMap, comparisonTime, Style.CHARS, 3);
    }

    @SuppressWarnings("unused")
    public long timeIteration(Map<String, Integer> testMap, long comparisonTime, Style style, double ratioToMap) {
        TrieMap<Integer> trieMap = TrieMap.BytesBuilder.with(style, Option.SMALL, testMap).build();
        TreeMap<String,Integer> expected = new TreeMap<String, Integer>(testMap);

        System.gc();
        t.start();
        if (style == null) {
            Map<String, Integer> map = comparisonTime == 0 ? new TreeMap<String, Integer>(testMap) : new HashMap<String, Integer>(testMap);

            long mapTime = t.timeIterations(new MyLoop() {
                @Override
                public void time(int repeat) {
                    for (int tt = 0; tt < repeat; ++tt) {
                        for (Entry<String, Integer> entry : map.entrySet()) {
                            String key = entry.getKey();
                            Integer value = entry.getValue();
                        }
                    }
                }
            }, null, map);
            if (comparisonTime == 0) {
                logln("\titeration time\tTREEMAP\tn/a\t" + t.toString(testMap.size()) + "\t\titerations=" + t.getIterations());
            } else {
                logln("\titeration time\tHASHMAP\tn/a\t" + t.toString(testMap.size(), comparisonTime) + "\titerations=" + t.getIterations());
            }
            return mapTime;
        } else {
            long trieTime = t.timeIterations(new MyLoop() {
                @Override
                public void time(int repeat) {
                    for (int tt = 0; tt < repeat; ++tt) {
                        for (Entry<CharSequence, Integer> entry : trieMap) {
                            CharSequence key = entry.getKey();
                            Integer value = entry.getValue();
                        }
                    }
                }
            }, null, trieMap);
            logln("\titeration time\t" + style + "\tn/a\t" + t.toString(testMap.size(), comparisonTime) + "\titerations=" + t.getIterations());
            if (!useSmallList && trieTime > ratioToMap * comparisonTime) {
                errln(style + "\tTime iteration takes too long. Expected:\t< " + ratioToMap * comparisonTime + ", Actual:\t" + trieTime);
            }
            return trieTime;
        }
    }

    @Ignore
    @Test
    public void TestContents() {
        checkContents(unicodeTestMap, Style.BYTES);
        checkContents(unicodeTestMap, Style.CHARS);
    }

    public void checkContents(Map<String, Integer> testMap, Style style) {
        if (testMap.size() == 0) {
            return;
        }
        TrieMap<Integer> trieMap = TrieMap.BytesBuilder.with(style, Option.SMALL, testMap).build();
        TreeMap<String,Integer> expected = new TreeMap<String, Integer>(testMap);
        Iterator<Entry<CharSequence, Integer>> trieIterator = trieMap.iterator();
        Iterator<Entry<String, Integer>> mapIterator = expected.entrySet().iterator();
        while (true) {
            boolean trieOk = trieIterator.hasNext();
            boolean mapOk = mapIterator.hasNext();
            if (mapOk!=trieOk) {
                assertEquals("Iterators end at same point", mapOk, trieOk);
            }

            if (!mapOk) break;
            Entry<CharSequence, Integer> trieEntry = trieIterator.next();
            Entry<String, Integer> mapEntry = mapIterator.next();
            String mapKey = mapEntry.getKey();
            CharSequence trieKey = trieEntry.getKey();
            if (!mapKey.contentEquals(trieKey)) {
                assertEquals(style + "\tKeys match", mapKey, trieKey.toString());
            }
            Integer mapValue = mapEntry.getValue();
            Integer trieValue = trieEntry.getValue();
            if (!mapValue.equals(trieValue)) {
                assertEquals(style + "\tValues match", mapValue, trieValue);
            }
        }
    }

    @Ignore
    @Test
    public void TestSearch() {
        checkSearch(Style.BYTES);
        checkSearch(Style.CHARS);
    }

    public void checkSearch(Style style) {

        TrieMap<String> trieMap = TrieMap.BytesBuilder.with(style, Option.SMALL, "abc", "first")
        .add("cdab", "fifth")
        .add("abcde", "second")
        .add("abdfg", "third").build();

        String string = "xabcdab abcde abdfg";
        @SuppressWarnings("unchecked")
        Row.R3<Integer, Integer, String>[] expected = new Row.R3[] {
            Row.of(1,4,"first"),
            Row.of(3,7,"fifth"),
            Row.of(8,11,"first"),
            Row.of(8,13,"second"),
            Row.of(14,19,"third"),
        };
        List<R3<Integer, Integer, String>> expectedList = Arrays.asList(expected);
        List<R3<Integer, Integer, String>> actualList = new ArrayList<R3<Integer, Integer, String>>();

        TrieMap.Matcher<String> matcher = trieMap.getMatcher();
        matcher.set(string, 0);
        do {
            boolean hasMore;
            do {
                hasMore = matcher.next();
                String value = matcher.getValue();
                if (value != null) {
                    int start = matcher.getStart();
                    int end = matcher.getEnd();
                    actualList.add(Row.of(start,end,value));
                }
            } while (hasMore);
        } while (matcher.nextStart());
        assertEquals(style + "\tTrieMap matcher", expectedList, actualList);
        //        logln(bytes + "\tValue <" + value + "> at "
        //                + start + ".." + end + ", "
        //                + string.substring(0, start) + "|"
        //                + string.substring(start, end) + "|"
        //                + string.substring(end)
        //        );
    }

    @Ignore
    @Test
    public void TestTimeBuilding() {
        long comparisonTime = timeBuilding(unicodeTestMap, 0, null, Option.SMALL, 0);
        timeBuilding(unicodeTestMap, comparisonTime, null, Option.SMALL, 0);
        timeBuilding(unicodeTestMap, comparisonTime, Style.BYTES, Option.SMALL, 20);
        timeBuilding(unicodeTestMap, comparisonTime, Style.BYTES, Option.FAST, 20);
        timeBuilding(unicodeTestMap, comparisonTime, Style.CHARS, Option.SMALL, 20);
        timeBuilding(unicodeTestMap, comparisonTime, Style.CHARS, Option.FAST, 20);
    }

    @SuppressWarnings("unused")
    public long timeBuilding(Map<String, Integer> testmap, long comparisonTime, Style style, Option option, double ratioToMap) {
        System.gc();
        t.start();
        if (style == null) {
            if (comparisonTime == 0) {
                long mapTime = t.timeIterations(new MyLoop() {
                    @Override
                    public void time(int repeat) {
                        for (int tt = 0; tt < repeat; ++tt) {
                            Map<String, Integer> map2 = new TreeMap<String, Integer>(map);
                        }
                    }
                }, null, testmap);
                logln("\tbuild time\tTREEMAP\tn/a\t" + t.toString(testmap.size()) + "\t\titerations=" + t.getIterations());
                return mapTime;
            } else {
                long mapTime = t.timeIterations(new MyLoop() {
                    @Override
                    public void time(int repeat) {
                        for (int tt = 0; tt < repeat; ++tt) {
                            Map<String, Integer> map2 = new HashMap<String, Integer>(map);
                        }
                    }
                }, null, testmap);
                logln("\tbuild time\tHASHMAP\tn/a\t" + t.toString(testmap.size(), comparisonTime) + "\titerations=" + t.getIterations());
                return mapTime;
            }
        } else {
            long trieTime = t.timeIterations(new MyLoop() {
                @Override
                public void time(int repeat) {
                    for (int tt = 0; tt < repeat; ++tt) {
                        trieMap = TrieMap.BytesBuilder.with(style, option, map).build();
                    }
                }
            }, null, testmap, style, option);

            logln("\tbuild time\t" + style + "\t" + option + "\t" + t.toString(testmap.size(), comparisonTime) + "\titerations=" + t.getIterations());
            if (!useSmallList && trieTime > ratioToMap * comparisonTime) {
                errln(style + "\t" + option + "\tTrie build takes too long. Expected:\t< " + nf.format(ratioToMap * comparisonTime) + ", Actual:\t" + nf.format(trieTime));
            }
            return trieTime;
        }
    }

    @Ignore
    @Test
    public void TestSize() {
        int size = checkSize(0, null, Option.SMALL, 0);
        checkSize(size, Style.BYTES, Option.SMALL, 0.20);
        checkSize(size, Style.BYTES, Option.FAST, 0.20);
        checkSize(size, Style.CHARS, Option.SMALL, 0.30);
        checkSize(size, Style.CHARS, Option.FAST, 0.30);
    }

    /**
     * @param option TODO
     * @param ratioToMap TODO
     * @param bytes
     */
    private int checkSize(int comparisonSize, Style style, Option option, double ratioToMap) {
        if (style == null) {
            int mapKeyByteSize = 0;
            TreeMap<String, Integer> map = new TreeMap<String, Integer>(unicodeTestMap);
            for (Entry<String, Integer> entry : map.entrySet()) {
                mapKeyByteSize += 8 * ((((entry.getKey().length()) * 2) + 45) / 8);
            }
            logln("\tkey byte size\tTREEMAP\tn/a\t" + nf.format(mapKeyByteSize));
            return mapKeyByteSize;
        } else {
            TrieMap<Integer> trieMap = TrieMap.BytesBuilder.with(style, option, unicodeTestMap).build();

            int trieKeyByteSize = trieMap.keyByteSize();
            logln("\tkey byte size\t" + style + "\t" + option + "\t" + nf.format(trieKeyByteSize) + "\t\t" + pf.format(trieKeyByteSize/(double)comparisonSize - 1D) + "");


            if (!useSmallList && trieKeyByteSize > ratioToMap * comparisonSize) {
                errln(style + "\t" + option + "\ttrieKeyByteSize too large. Expected:\t< " + nf.format(ratioToMap * comparisonSize) + ", Actual:\t" + nf.format(trieKeyByteSize));
            }
            return trieKeyByteSize;
        }
    }

    @Ignore
	@Test
    public void TestTimeGet() {
        HashSet<String> keySet = new HashSet<String>(unicodeTestMap.keySet());
        ULocale[] locales = ULocale.getAvailableLocales();
        int i = 0;
        for (ULocale locale : locales) {
            if (locale.getDisplayCountry().length() != 0) {
                continue;
            }
            String localeName;
            for (int scriptCodeInt = 0; scriptCodeInt < UScript.CODE_LIMIT; ++scriptCodeInt) {
                String scriptCode = UScript.getShortName(scriptCodeInt);
                localeName = ULocale.getDisplayScript("und-" + scriptCode, locale);
                if (!localeName.equals(scriptCode)) {
                    if (!keySet.contains(localeName)) {
                        keySet.add(localeName);
                        ++i;
                    }
                    if (SHORT) break;
                }
            }
        }
        logln("\tExtra Key Elements\t" + i);

        ArrayList<String> keys = new ArrayList<String>(keySet);

        long comparisonTime = timeGet(keys, unicodeTestMap, 0, null, 0);
        timeGet(keys, unicodeTestMap, comparisonTime, null, 0);
        timeGet(keys, unicodeTestMap, comparisonTime, Style.BYTES, 3);
        timeGet(keys, unicodeTestMap, comparisonTime, Style.CHARS, 3);
    }

    @SuppressWarnings("unused")
    public long timeGet(ArrayList<String> keys, Map<String, Integer> testmap, long comparisonTime, Style style, int ratioToMap) {

        TrieMap<Integer> trieMap = TrieMap.Builder.with(style, Option.SMALL, testmap).build();

        if (style == null) {
            Map<String, Integer> map = comparisonTime == 0 ? new TreeMap<String, Integer>(testmap) : new HashMap<String, Integer>(testmap);

            long mapTime = t.timeIterations(new MyLoop() {
                @Override
                public void time(int repeat) {
                    for (int tt = 0; tt < repeat; ++tt) {
                        for (String key : keys) {
                            Integer foundValue = map.get(key);
                        }
                    }
                }
            }, keys, map);
            if (comparisonTime == 0) {
                logln("\tget() time\tTREEMAP\tn/a\t" + t.toString(keys.size()) + "\t\titerations=" + t.getIterations());
            } else {
                logln("\tget() time\tHASHMAP\tn/a\t" + t.toString(keys.size(), comparisonTime) + "\titerations=" + t.getIterations());
            }
            return mapTime;
        } else {
            long trieTime = t.timeIterations(new MyLoop() {
                @Override
                public void time(int repeat) {
                    for (int tt = 0; tt < repeat; ++tt) {
                        for (String key : keys) {
                            Integer foundValue = trieMap.get(key);
                        }
                    }
                }
            }, keys, trieMap);

            //            System.gc();
            //            t.start();
            //            for (int tt = 0; tt < repeat; ++tt) {
            //                for (String key : keys) {
            //                    Integer foundValue = trieMap.get(key);
            //                }
            //            }
            //            long trieTime = t.getDuration();
            logln("\tget() time\t" + style + "\tn/a\t" + t.toString(keys.size(), comparisonTime) + "\titerations=" + t.getIterations());
            if (!useSmallList && trieTime > ratioToMap * comparisonTime) {
                errln(style + "\tTime iteration takes too long. Expected:\t< " + ratioToMap * comparisonTime + ", Actual:\t" + trieTime);
            }
            return trieTime;
        }
    }

    static abstract class MyLoop extends Timer.Loop {
        ArrayList<String> keys;
        TrieMap<Integer> trieMap;
        Map<String, Integer> map;
        Style style;
        Option option;
        @Override
        public void init(Object... params) {
            if (params.length > 0) {
                keys = (ArrayList<String>) params[0];
            }
            if (params.length > 1) {
                if (params[1] instanceof Map) {
                    map = (Map<String, Integer>) params[1];
                } else {
                    trieMap = (TrieMap<Integer>) params[1];
                }
            }
            if (params.length > 2) {
                style = (Style) params[2];
            }
            if (params.length > 3) {
                option = (Option) params[3];
            }
        }
        @Override
        abstract public void time(int repeat);
    }

    //    static class Storage {
    //        char[] buffer;
    //        int limit;
    //
    //        public Storage(int initialCapacity) {
    //            buffer = new char[initialCapacity];
    //        }
    //
    //        public CharSequence add(CharSequence input) {
    //            int start = limit;
    //            int length = input.length();
    //            for (int i = 0; i < length; ++i) {
    //                try {
    //                    buffer[limit++] = input.charAt(i);
    //                } catch (Exception e) {
    //                    // we failed to add (limit-1)
    //                    int newCapacity = buffer.length * 3 / 2 + length;
    //                    //System.out.println(buffer.length + " => " + newCapacity);
    //                    char[] temp = new char[newCapacity];
    //                    System.arraycopy(buffer, 0, temp, 0, buffer.length);
    //                    buffer = temp;
    //                    buffer[limit - 1] = input.charAt(i);
    //                }
    //            }
    //            return new StorageCharSequence(start, limit);
    //        }
    //
    //        final class StorageCharSequence implements CharSequence, Comparable<CharSequence> {
    //            private int start;
    //            private int len;
    //
    //            public StorageCharSequence(int start, int limit) {
    //                if (start < 0 || start > limit || limit > buffer.length) {
    //                    throw new ArrayIndexOutOfBoundsException();
    //                }
    //                this.start = start;
    //                this.len = limit - start;
    //            }
    //            public char charAt(int arg0) {
    //                return arg0 < 0 || arg0 >= len ? buffer[-1] : buffer[arg0 + start];
    //            }
    //            public int length() {
    //                return len;
    //            }
    //            public CharSequence subSequence(int start, int limit) {
    //                return new StorageCharSequence(this.start + start, this.start + limit);
    //            }
    //            public String toString() {
    //                return String.valueOf(buffer, start, len);
    //            }
    //            public int hashCode() {
    //                int result = len;
    //                int limit = start + len;
    //                for (int i = start; i < limit; ++i) {
    //                    result *= 37;
    //                    result += i;
    //                }
    //                return result;
    //            }
    //            public boolean equals(Object other) {
    //                try {
    //                    StorageCharSequence that = (StorageCharSequence) other;
    //                    // can optimize
    //                    return CharSequences.equalsChars(this, that);
    //                } catch (Exception e) {
    //                    return false;
    //                }
    //            }
    //            public int compareTo(CharSequence other) {
    //                // can optimize
    //                return CharSequences.compare(this, other);
    //            }
    //        }
    //
    //    }
    //    public void TestStorage() {
    //        ArrayList<String> keys = new ArrayList<String>(unicodeTestMap.keySet());
    //        int repeat = REPEAT * 10;
    //        System.gc();
    //        t.start();
    //        for (int tt = 0; tt < repeat; ++tt) {
    //            Set<CharSequence> store = new HashSet<CharSequence>();
    //            // Storage storage = new Storage(1024);
    //            for (String key : keys) {
    //                store.add(key);
    //                //                CharSequence item = storage.add(key);
    //                //                if (!store.contains(item)) {
    //                //                    store.add(item);
    //                //                }
    //                //                if (!CharSequences.equalsChars(key, item)) {
    //                //                    throw new IllegalArgumentException(key);
    //                //                }
    //            }
    //            CharSequence[] raw = store.toArray(new CharSequence[store.size()]);
    //            Arrays.sort(raw);
    //        }
    //        long comparisonTime = t.getDuration();
    //        logln("\tget() time\tHashSet,sort\tn/a\t" + t.toString(repeat*keys.size()));
    //
    //        System.gc();
    //        t.start();
    //        for (int tt = 0; tt < repeat; ++tt) {
    //            Set<CharSequence> store = new TreeSet<CharSequence>();
    //            for (String key : keys) {
    //                store.add(key);
    //            }
    //            CharSequence[] raw = store.toArray(new CharSequence[store.size()]);
    //        }
    //        long trieTime = t.getDuration();
    //        logln("\tget() time\tTreeSet\tn/a\t" + t.toString(repeat*keys.size(), comparisonTime));
    //
    //    }
}
