// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
*******************************************************************************
* Copyright (C) 2013-2015, International Business Machines
* Corporation and others.  All Rights Reserved.
*******************************************************************************
* CollationFastLatinBuilder.java, ported from collationfastlatinbuilder.h/.cpp
*
* C++ version created on: 2013aug09
* created by: Markus W. Scherer
*/

package com.ibm.icu.impl.coll;

import com.ibm.icu.lang.UScript;
import com.ibm.icu.text.Collator;
import com.ibm.icu.util.CharsTrie;

final class CollationFastLatinBuilder {
    // #define DEBUG_COLLATION_FAST_LATIN_BUILDER 0  // 0 or 1 or 2

    /**
     * Compare two signed long values as if they were unsigned.
     */
    private static final int compareInt64AsUnsigned(long a, long b) {
        a += 0x8000000000000000L;
        b += 0x8000000000000000L;
        if(a < b) {
            return -1;
        } else if(a > b) {
            return 1;
        } else {
            return 0;
        }
    }

    /**
     * Like Java Collections.binarySearch(List, String, Comparator).
     *
     * @return the index>=0 where the item was found,
     *         or the index<0 for inserting the string at ~index in sorted order
     */
    private static final int binarySearch(long[] list, int limit, long ce) {
        if (limit == 0) { return ~0; }
        int start = 0;
        for (;;) {
            int i = (start + limit) / 2;
            int cmp = compareInt64AsUnsigned(ce, list[i]);
            if (cmp == 0) {
                return i;
            } else if (cmp < 0) {
                if (i == start) {
                    return ~start;  // insert ce before i
                }
                limit = i;
            } else {
                if (i == start) {
                    return ~(start + 1);  // insert ce after i
                }
                start = i;
            }
        }
    }

    CollationFastLatinBuilder() {
        ce0 = 0;
        ce1 = 0;
        contractionCEs = new UVector64();
        uniqueCEs = new UVector64();
        miniCEs = null;
        firstDigitPrimary = 0;
        firstLatinPrimary = 0;
        lastLatinPrimary = 0;
        firstShortPrimary = 0;
        shortPrimaryOverflow = false;
        headerLength = 0;
    }

    boolean forData(CollationData data) {
        if(result.length() != 0) {  // This builder is not reusable.
            throw new IllegalStateException("attempt to reuse a CollationFastLatinBuilder");
        }
        if(!loadGroups(data)) { return false; }

        // Fast handling of digits.
        firstShortPrimary = firstDigitPrimary;
        getCEs(data);
        encodeUniqueCEs();
        if(shortPrimaryOverflow) {
            // Give digits long mini primaries,
            // so that there are more short primaries for letters.
            firstShortPrimary = firstLatinPrimary;
            resetCEs();
            getCEs(data);
            encodeUniqueCEs();
        }
        // Note: If we still have a short-primary overflow but not a long-primary overflow,
        // then we could calculate how many more long primaries would fit,
        // and set the firstShortPrimary to that many after the current firstShortPrimary,
        // and try again.
        // However, this might only benefit the en_US_POSIX tailoring,
        // and it is simpler to suppress building fast Latin data for it in genrb,
        // or by returning false here if shortPrimaryOverflow.

        boolean ok = !shortPrimaryOverflow;
        if(ok) {
            encodeCharCEs();
            encodeContractions();
        }
        contractionCEs.removeAllElements();  // might reduce heap memory usage
        uniqueCEs.removeAllElements();
        return ok;
    }

    // C++ returns one combined array with the contents of the result buffer.
    // Java returns two arrays (header & table) because we cannot use pointer arithmetic,
    // and we do not want to index into the table with an offset.
    char[] getHeader() {
        char[] resultArray = new char[headerLength];
        result.getChars(0, headerLength, resultArray, 0);
        return resultArray;
    }

    char[] getTable() {
        char[] resultArray = new char[result.length() - headerLength];
        result.getChars(headerLength, result.length(), resultArray, 0);
        return resultArray;
    }

    private boolean loadGroups(CollationData data) {
        headerLength = 1 + NUM_SPECIAL_GROUPS;
        int r0 = (CollationFastLatin.VERSION << 8) | headerLength;
        result.append((char)r0);
        // The first few reordering groups should be special groups
        // (space, punct, ..., digit) followed by Latn, then Grek and other scripts.
        for(int i = 0; i < NUM_SPECIAL_GROUPS; ++i) {
            lastSpecialPrimaries[i] = data.getLastPrimaryForGroup(Collator.ReorderCodes.FIRST + i);
            if(lastSpecialPrimaries[i] == 0) {
                // missing data
                return false;
            }
            result.append(0);  // reserve a slot for this group
        }

        firstDigitPrimary = data.getFirstPrimaryForGroup(Collator.ReorderCodes.DIGIT);
        firstLatinPrimary = data.getFirstPrimaryForGroup(UScript.LATIN);
        lastLatinPrimary = data.getLastPrimaryForGroup(UScript.LATIN);
        if(firstDigitPrimary == 0 || firstLatinPrimary == 0) {
            // missing data
            return false;
        }
        return true;
    }

    private boolean inSameGroup(long p, long q) {
        // Both or neither need to be encoded as short primaries,
        // so that we can test only one and use the same bit mask.
        if(p >= firstShortPrimary) {
            return q >= firstShortPrimary;
        } else if(q >= firstShortPrimary) {
            return false;
        }
        // Both or neither must be potentially-variable,
        // so that we can test only one and determine if both are variable.
        long lastVariablePrimary = lastSpecialPrimaries[NUM_SPECIAL_GROUPS - 1];
        if(p > lastVariablePrimary) {
            return q > lastVariablePrimary;
        } else if(q > lastVariablePrimary) {
            return false;
        }
        // Both will be encoded with long mini primaries.
        // They must be in the same special reordering group,
        // so that we can test only one and determine if both are variable.
        assert(p != 0 && q != 0);
        for(int i = 0;; ++i) {  // will terminate
            long lastPrimary = lastSpecialPrimaries[i];
            if(p <= lastPrimary) {
                return q <= lastPrimary;
            } else if(q <= lastPrimary) {
                return false;
            }
        }
    }

    private void resetCEs() {
        contractionCEs.removeAllElements();
        uniqueCEs.removeAllElements();
        shortPrimaryOverflow = false;
        result.setLength(headerLength);
    }

    private void getCEs(CollationData data) {
        int i = 0;
        for(char c = 0;; ++i, ++c) {
            if(c == CollationFastLatin.LATIN_LIMIT) {
                c = CollationFastLatin.PUNCT_START;
            } else if(c == CollationFastLatin.PUNCT_LIMIT) {
                break;
            }
            CollationData d;
            int ce32 = data.getCE32(c);
            if(ce32 == Collation.FALLBACK_CE32) {
                d = data.base;
                ce32 = d.getCE32(c);
            } else {
                d = data;
            }
            if(getCEsFromCE32(d, c, ce32)) {
                charCEs[i][0] = ce0;
                charCEs[i][1] = ce1;
                addUniqueCE(ce0);
                addUniqueCE(ce1);
            } else {
                // bail out for c
                charCEs[i][0] = ce0 = Collation.NO_CE;
                charCEs[i][1] = ce1 = 0;
            }
            if(c == 0 && !isContractionCharCE(ce0)) {
                // Always map U+0000 to a contraction.
                // Write a contraction list with only a default value if there is no real contraction.
                assert(contractionCEs.isEmpty());
                addContractionEntry(CollationFastLatin.CONTR_CHAR_MASK, ce0, ce1);
                charCEs[0][0] = (Collation.NO_CE_PRIMARY << 32) | CONTRACTION_FLAG;
                charCEs[0][1] = 0;
            }
        }
        // Terminate the last contraction list.
        contractionCEs.addElement(CollationFastLatin.CONTR_CHAR_MASK);
    }

    private boolean getCEsFromCE32(CollationData data, int c, int ce32) {
        ce32 = data.getFinalCE32(ce32);
        ce1 = 0;
        if(Collation.isSimpleOrLongCE32(ce32)) {
            ce0 = Collation.ceFromCE32(ce32);
        } else {
            switch(Collation.tagFromCE32(ce32)) {
            case Collation.LATIN_EXPANSION_TAG:
                ce0 = Collation.latinCE0FromCE32(ce32);
                ce1 = Collation.latinCE1FromCE32(ce32);
                break;
            case Collation.EXPANSION32_TAG: {
                int index = Collation.indexFromCE32(ce32);
                int length = Collation.lengthFromCE32(ce32);
                if(length <= 2) {
                    ce0 = Collation.ceFromCE32(data.ce32s[index]);
                    if(length == 2) {
                        ce1 = Collation.ceFromCE32(data.ce32s[index + 1]);
                    }
                    break;
                } else {
                    return false;
                }
            }
            case Collation.EXPANSION_TAG: {
                int index = Collation.indexFromCE32(ce32);
                int length = Collation.lengthFromCE32(ce32);
                if(length <= 2) {
                    ce0 = data.ces[index];
                    if(length == 2) {
                        ce1 = data.ces[index + 1];
                    }
                    break;
                } else {
                    return false;
                }
            }
            // Note: We could support PREFIX_TAG (assert c>=0)
            // by recursing on its default CE32 and checking that none of the prefixes starts
            // with a fast Latin character.
            // However, currently (2013) there are only the L-before-middle-dot
            // prefix mappings in the Latin range, and those would be rejected anyway.
            case Collation.CONTRACTION_TAG:
                assert(c >= 0);
                return getCEsFromContractionCE32(data, ce32);
            case Collation.OFFSET_TAG:
                assert(c >= 0);
                ce0 = data.getCEFromOffsetCE32(c, ce32);
                break;
            default:
                return false;
            }
        }
        // A mapping can be completely ignorable.
        if(ce0 == 0) { return ce1 == 0; }
        // We do not support an ignorable ce0 unless it is completely ignorable.
        long p0 = ce0 >>> 32;
        if(p0 == 0) { return false; }
        // We only support primaries up to the Latin script.
        if(p0 > lastLatinPrimary) { return false; }
        // We support non-common secondary and case weights only together with short primaries.
        int lower32_0 = (int)ce0;
        if(p0 < firstShortPrimary) {
            int sc0 = lower32_0 & Collation.SECONDARY_AND_CASE_MASK;
            if(sc0 != Collation.COMMON_SECONDARY_CE) { return false; }
        }
        // No below-common tertiary weights.
        if((lower32_0 & Collation.ONLY_TERTIARY_MASK) < Collation.COMMON_WEIGHT16) { return false; }
        if(ce1 != 0) {
            // Both primaries must be in the same group,
            // or both must get short mini primaries,
            // or a short-primary CE is followed by a secondary CE.
            // This is so that we can test the first primary and use the same mask for both,
            // and determine for both whether they are variable.
            long p1 = ce1 >>> 32;
            if(p1 == 0 ? p0 < firstShortPrimary : !inSameGroup(p0, p1)) { return false; }
            int lower32_1 = (int)ce1;
            // No tertiary CEs.
            if((lower32_1 >>> 16) == 0) { return false; }
            // We support non-common secondary and case weights
            // only for secondary CEs or together with short primaries.
            if(p1 != 0 && p1 < firstShortPrimary) {
                int sc1 = lower32_1 & Collation.SECONDARY_AND_CASE_MASK;
                if(sc1 != Collation.COMMON_SECONDARY_CE) { return false; }
            }
            // No below-common tertiary weights.
            if((lower32_0 & Collation.ONLY_TERTIARY_MASK) < Collation.COMMON_WEIGHT16) { return false; }
        }
        // No quaternary weights.
        if(((ce0 | ce1) & Collation.QUATERNARY_MASK) != 0) { return false; }
        return true;
    }

    private boolean getCEsFromContractionCE32(CollationData data, int ce32) {
        int trieIndex = Collation.indexFromCE32(ce32);
        ce32 = data.getCE32FromContexts(trieIndex);  // Default if no suffix match.
        // Since the original ce32 is not a prefix mapping,
        // the default ce32 must not be another contraction.
        assert(!Collation.isContractionCE32(ce32));
        int contractionIndex = contractionCEs.size();
        if(getCEsFromCE32(data, Collation.SENTINEL_CP, ce32)) {
            addContractionEntry(CollationFastLatin.CONTR_CHAR_MASK, ce0, ce1);
        } else {
            // Bail out for c-without-contraction.
            addContractionEntry(CollationFastLatin.CONTR_CHAR_MASK, Collation.NO_CE, 0);
        }
        // Handle an encodable contraction unless the next contraction is too long
        // and starts with the same character.
        int prevX = -1;
        boolean addContraction = false;
        CharsTrie.Iterator suffixes = CharsTrie.iterator(data.contexts, trieIndex + 2, 0);
        while(suffixes.hasNext()) {
            CharsTrie.Entry entry = suffixes.next();
            CharSequence suffix = entry.chars;
            int x = CollationFastLatin.getCharIndex(suffix.charAt(0));
            if(x < 0) { continue; }  // ignore anything but fast Latin text
            if(x == prevX) {
                if(addContraction) {
                    // Bail out for all contractions starting with this character.
                    addContractionEntry(x, Collation.NO_CE, 0);
                    addContraction = false;
                }
                continue;
            }
            if(addContraction) {
                addContractionEntry(prevX, ce0, ce1);
            }
            ce32 = entry.value;
            if(suffix.length() == 1 && getCEsFromCE32(data, Collation.SENTINEL_CP, ce32)) {
                addContraction = true;
            } else {
                addContractionEntry(x, Collation.NO_CE, 0);
                addContraction = false;
            }
            prevX = x;
        }
        if(addContraction) {
            addContractionEntry(prevX, ce0, ce1);
        }
        // Note: There might not be any fast Latin contractions, but
        // we need to enter contraction handling anyway so that we can bail out
        // when there is a non-fast-Latin character following.
        // For example: Danish &Y<<u+umlaut, when we compare Y vs. u\u0308 we need to see the
        // following umlaut and bail out, rather than return the difference of Y vs. u.
        ce0 = (Collation.NO_CE_PRIMARY << 32) | CONTRACTION_FLAG | contractionIndex;
        ce1 = 0;
        return true;
    }

    private void addContractionEntry(int x, long cce0, long cce1) {
        contractionCEs.addElement(x);
        contractionCEs.addElement(cce0);
        contractionCEs.addElement(cce1);
        addUniqueCE(cce0);
        addUniqueCE(cce1);
    }

    private void addUniqueCE(long ce) {
        if(ce == 0 || (ce >>> 32) == Collation.NO_CE_PRIMARY) { return; }
        ce &= ~(long)Collation.CASE_MASK;  // blank out case bits
        int i = binarySearch(uniqueCEs.getBuffer(), uniqueCEs.size(), ce);
        if(i < 0) {
            uniqueCEs.insertElementAt(ce, ~i);
        }
    }

    private int getMiniCE(long ce) {
        ce &= ~(long)Collation.CASE_MASK;  // blank out case bits
        int index = binarySearch(uniqueCEs.getBuffer(), uniqueCEs.size(), ce);
        assert(index >= 0);
        return miniCEs[index];
    }

    private void encodeUniqueCEs() {
        miniCEs = new char[uniqueCEs.size()];
        int group = 0;
        long lastGroupPrimary = lastSpecialPrimaries[group];
        // The lowest unique CE must be at least a secondary CE.
        assert(((int)uniqueCEs.elementAti(0) >>> 16) != 0);
        long prevPrimary = 0;
        int prevSecondary = 0;
        int pri = 0;
        int sec = 0;
        int ter = CollationFastLatin.COMMON_TER;
        for(int i = 0; i < uniqueCEs.size(); ++i) {
            long ce = uniqueCEs.elementAti(i);
            // Note: At least one of the p/s/t weights changes from one unique CE to the next.
            // (uniqueCEs does not store case bits.)
            long p = ce >>> 32;
            if(p != prevPrimary) {
                while(p > lastGroupPrimary) {
                    assert(pri <= CollationFastLatin.MAX_LONG);
                    // Set the group's header entry to the
                    // last "long primary" in or before the group.
                    result.setCharAt(1 + group, (char)pri);
                    if(++group < NUM_SPECIAL_GROUPS) {
                        lastGroupPrimary = lastSpecialPrimaries[group];
                    } else {
                        lastGroupPrimary = 0xffffffffL;
                        break;
                    }
                }
                if(p < firstShortPrimary) {
                    if(pri == 0) {
                        pri = CollationFastLatin.MIN_LONG;
                    } else if(pri < CollationFastLatin.MAX_LONG) {
                        pri += CollationFastLatin.LONG_INC;
                    } else {
    /* #if DEBUG_COLLATION_FAST_LATIN_BUILDER
                        printf("long-primary overflow for %08x\n", p);
    #endif */
                        miniCEs[i] = CollationFastLatin.BAIL_OUT;
                        continue;
                    }
                } else {
                    if(pri < CollationFastLatin.MIN_SHORT) {
                        pri = CollationFastLatin.MIN_SHORT;
                    } else if(pri < (CollationFastLatin.MAX_SHORT - CollationFastLatin.SHORT_INC)) {
                        // Reserve the highest primary weight for U+FFFF.
                        pri += CollationFastLatin.SHORT_INC;
                    } else {
    /* #if DEBUG_COLLATION_FAST_LATIN_BUILDER
                        printf("short-primary overflow for %08x\n", p);
    #endif */
                        shortPrimaryOverflow = true;
                        miniCEs[i] = CollationFastLatin.BAIL_OUT;
                        continue;
                    }
                }
                prevPrimary = p;
                prevSecondary = Collation.COMMON_WEIGHT16;
                sec = CollationFastLatin.COMMON_SEC;
                ter = CollationFastLatin.COMMON_TER;
            }
            int lower32 = (int)ce;
            int s = lower32 >>> 16;
            if(s != prevSecondary) {
                if(pri == 0) {
                    if(sec == 0) {
                        sec = CollationFastLatin.MIN_SEC_HIGH;
                    } else if(sec < CollationFastLatin.MAX_SEC_HIGH) {
                        sec += CollationFastLatin.SEC_INC;
                    } else {
                        miniCEs[i] = CollationFastLatin.BAIL_OUT;
                        continue;
                    }
                    prevSecondary = s;
                    ter = CollationFastLatin.COMMON_TER;
                } else if(s < Collation.COMMON_WEIGHT16) {
                    if(sec == CollationFastLatin.COMMON_SEC) {
                        sec = CollationFastLatin.MIN_SEC_BEFORE;
                    } else if(sec < CollationFastLatin.MAX_SEC_BEFORE) {
                        sec += CollationFastLatin.SEC_INC;
                    } else {
                        miniCEs[i] = CollationFastLatin.BAIL_OUT;
                        continue;
                    }
                } else if(s == Collation.COMMON_WEIGHT16) {
                    sec = CollationFastLatin.COMMON_SEC;
                } else {
                    if(sec < CollationFastLatin.MIN_SEC_AFTER) {
                        sec = CollationFastLatin.MIN_SEC_AFTER;
                    } else if(sec < CollationFastLatin.MAX_SEC_AFTER) {
                        sec += CollationFastLatin.SEC_INC;
                    } else {
                        miniCEs[i] = CollationFastLatin.BAIL_OUT;
                        continue;
                    }
                }
                prevSecondary = s;
                ter = CollationFastLatin.COMMON_TER;
            }
            assert((lower32 & Collation.CASE_MASK) == 0);  // blanked out in uniqueCEs
            int t = lower32 & Collation.ONLY_TERTIARY_MASK;
            if(t > Collation.COMMON_WEIGHT16) {
                if(ter < CollationFastLatin.MAX_TER_AFTER) {
                    ++ter;
                } else {
                    miniCEs[i] = CollationFastLatin.BAIL_OUT;
                    continue;
                }
            }
            if(CollationFastLatin.MIN_LONG <= pri && pri <= CollationFastLatin.MAX_LONG) {
                assert(sec == CollationFastLatin.COMMON_SEC);
                miniCEs[i] = (char)(pri | ter);
            } else {
                miniCEs[i] = (char)(pri | sec | ter);
            }
        }
    /* #if DEBUG_COLLATION_FAST_LATIN_BUILDER
        printf("last mini primary: %04x\n", pri);
    #endif */
    /* #if DEBUG_COLLATION_FAST_LATIN_BUILDER >= 2
        for(int i = 0; i < uniqueCEs.size(); ++i) {
            long ce = uniqueCEs.elementAti(i);
            printf("unique CE 0x%016lx -> 0x%04x\n", ce, miniCEs[i]);
        }
    #endif */
    }

    private void encodeCharCEs() {
        int miniCEsStart = result.length();
        for(int i = 0; i < CollationFastLatin.NUM_FAST_CHARS; ++i) {
            result.append(0);  // initialize to completely ignorable
        }
        int indexBase = result.length();
        for(int i = 0; i < CollationFastLatin.NUM_FAST_CHARS; ++i) {
            long ce = charCEs[i][0];
            if(isContractionCharCE(ce)) { continue; }  // defer contraction
            int miniCE = encodeTwoCEs(ce, charCEs[i][1]);
            if((miniCE >>> 16) > 0) {   // if ((unsigned)miniCE > 0xffff)
                // Note: There is a chance that this new expansion is the same as a previous one,
                // and if so, then we could reuse the other expansion.
                // However, that seems unlikely.
                int expansionIndex = result.length() - indexBase;
                if(expansionIndex > CollationFastLatin.INDEX_MASK) {
                    miniCE = CollationFastLatin.BAIL_OUT;
                } else {
                    result.append((char)(miniCE >> 16)).append((char)miniCE);
                    miniCE = CollationFastLatin.EXPANSION | expansionIndex;
                }
            }
            result.setCharAt(miniCEsStart + i, (char)miniCE);
        }
    }

    private void encodeContractions() {
        // We encode all contraction lists so that the first word of a list
        // terminates the previous list, and we only need one additional terminator at the end.
        int indexBase = headerLength + CollationFastLatin.NUM_FAST_CHARS;
        int firstContractionIndex = result.length();
        for(int i = 0; i < CollationFastLatin.NUM_FAST_CHARS; ++i) {
            long ce = charCEs[i][0];
            if(!isContractionCharCE(ce)) { continue; }
            int contractionIndex = result.length() - indexBase;
            if(contractionIndex > CollationFastLatin.INDEX_MASK) {
                result.setCharAt(headerLength + i, (char) CollationFastLatin.BAIL_OUT);
                continue;
            }
            boolean firstTriple = true;
            for(int index = (int)ce & 0x7fffffff;; index += 3) {
                long x = contractionCEs.elementAti(index);
                if(x == CollationFastLatin.CONTR_CHAR_MASK && !firstTriple) { break; }
                long cce0 = contractionCEs.elementAti(index + 1);
                long cce1 = contractionCEs.elementAti(index + 2);
                int miniCE = encodeTwoCEs(cce0, cce1);
                if(miniCE == CollationFastLatin.BAIL_OUT) {
                    result.append((char)(x | (1 << CollationFastLatin.CONTR_LENGTH_SHIFT)));
                } else if((miniCE >>> 16) == 0) {  // if ((unsigned)miniCE <= 0xffff)
                    result.append((char)(x | (2 << CollationFastLatin.CONTR_LENGTH_SHIFT)));
                    result.append((char)miniCE);
                } else {
                    result.append((char)(x | (3 << CollationFastLatin.CONTR_LENGTH_SHIFT)));
                    result.append((char)(miniCE >> 16)).append((char)miniCE);
                }
                firstTriple = false;
            }
            // Note: There is a chance that this new contraction list is the same as a previous one,
            // and if so, then we could truncate the result and reuse the other list.
            // However, that seems unlikely.
            result.setCharAt(headerLength + i,
                            (char)(CollationFastLatin.CONTRACTION | contractionIndex));
        }
        if(result.length() > firstContractionIndex) {
            // Terminate the last contraction list.
            result.append((char)CollationFastLatin.CONTR_CHAR_MASK);
        }
    /* #if DEBUG_COLLATION_FAST_LATIN_BUILDER
        printf("** fast Latin %d * 2 = %d bytes\n", result.length(), result.length() * 2);
        puts("   header & below-digit groups map");
        int i = 0;
        for(; i < headerLength; ++i) {
            printf(" %04x", result[i]);
        }
        printf("\n   char mini CEs");
        assert(CollationFastLatin.NUM_FAST_CHARS % 16 == 0);
        for(; i < indexBase; i += 16) {
            int c = i - headerLength;
            if(c >= CollationFastLatin.LATIN_LIMIT) {
                c = CollationFastLatin.PUNCT_START + c - CollationFastLatin.LATIN_LIMIT;
            }
            printf("\n %04x:", c);
            for(int j = 0; j < 16; ++j) {
                printf(" %04x", result[i + j]);
            }
        }
        printf("\n   expansions & contractions");
        for(; i < result.length(); ++i) {
            if((i - indexBase) % 16 == 0) { puts(""); }
            printf(" %04x", result[i]);
        }
        puts("");
    #endif */
    }

    private int encodeTwoCEs(long first, long second) {
        if(first == 0) {
            return 0;  // completely ignorable
        }
        if(first == Collation.NO_CE) {
            return CollationFastLatin.BAIL_OUT;
        }
        assert((first >>> 32) != Collation.NO_CE_PRIMARY);

        int miniCE = getMiniCE(first);
        if(miniCE == CollationFastLatin.BAIL_OUT) { return miniCE; }
        if(miniCE >= CollationFastLatin.MIN_SHORT) {
            // Extract & copy the case bits.
            // Shift them from normal CE bits 15..14 to mini CE bits 4..3.
            int c = (((int)first & Collation.CASE_MASK) >> (14 - 3));
            // Only in mini CEs: Ignorable case bits = 0, lowercase = 1.
            c += CollationFastLatin.LOWER_CASE;
            miniCE |= c;
        }
        if(second == 0) { return miniCE; }

        int miniCE1 = getMiniCE(second);
        if(miniCE1 == CollationFastLatin.BAIL_OUT) { return miniCE1; }

        int case1 = (int)second & Collation.CASE_MASK;
        if(miniCE >= CollationFastLatin.MIN_SHORT &&
                (miniCE & CollationFastLatin.SECONDARY_MASK) == CollationFastLatin.COMMON_SEC) {
            // Try to combine the two mini CEs into one.
            int sec1 = miniCE1 & CollationFastLatin.SECONDARY_MASK;
            int ter1 = miniCE1 & CollationFastLatin.TERTIARY_MASK;
            if(sec1 >= CollationFastLatin.MIN_SEC_HIGH && case1 == 0 &&
                    ter1 == CollationFastLatin.COMMON_TER) {
                // sec1>=sec_high implies pri1==0.
                return (miniCE & ~CollationFastLatin.SECONDARY_MASK) | sec1;
            }
        }

        if(miniCE1 <= CollationFastLatin.SECONDARY_MASK || CollationFastLatin.MIN_SHORT <= miniCE1) {
            // Secondary CE, or a CE with a short primary, copy the case bits.
            case1 = (case1 >> (14 - 3)) + CollationFastLatin.LOWER_CASE;
            miniCE1 |= case1;
        }
        return (miniCE << 16) | miniCE1;
    }

    private static boolean isContractionCharCE(long ce) {
        return (ce >>> 32) == Collation.NO_CE_PRIMARY && ce != Collation.NO_CE;
    }

    // space, punct, symbol, currency (not digit)
    private static final int NUM_SPECIAL_GROUPS =
            Collator.ReorderCodes.CURRENCY - Collator.ReorderCodes.FIRST + 1;

    private static final long CONTRACTION_FLAG = 0x80000000L;

    // temporary "buffer"
    private long ce0, ce1;

    private long[][] charCEs = new long[CollationFastLatin.NUM_FAST_CHARS][2];

    private UVector64 contractionCEs;
    private UVector64 uniqueCEs;

    /** One 16-bit mini CE per unique CE. */
    private char[] miniCEs;

    // These are constant for a given root collator.
    long[] lastSpecialPrimaries = new long[NUM_SPECIAL_GROUPS];
    private long firstDigitPrimary;
    private long firstLatinPrimary;
    private long lastLatinPrimary;
    // This determines the first normal primary weight which is mapped to
    // a short mini primary. It must be >=firstDigitPrimary.
    private long firstShortPrimary;

    private boolean shortPrimaryOverflow;

    private StringBuilder result = new StringBuilder();
    private int headerLength;
}
