/*
*******************************************************************************
* Copyright (C) 2013-2015, International Business Machines
* Corporation and others.  All Rights Reserved.
*******************************************************************************
* collationsettings.cpp
*
* created on: 2013feb07
* created by: Markus W. Scherer
*/

#include "unicode/utypes.h"

#if !UCONFIG_NO_COLLATION

#include "unicode/ucol.h"
#include "cmemory.h"
#include "collation.h"
#include "collationdata.h"
#include "collationsettings.h"
#include "sharedobject.h"
#include "uassert.h"
#include "umutex.h"
#include "uvectr32.h"

U_NAMESPACE_BEGIN

CollationSettings::CollationSettings(const CollationSettings &other)
        : SharedObject(other),
          options(other.options), variableTop(other.variableTop),
          reorderTable(NULL),
          minHighNoReorder(other.minHighNoReorder),
          reorderRanges(NULL), reorderRangesLength(0),
          reorderCodes(NULL), reorderCodesLength(0), reorderCodesCapacity(0),
          fastLatinOptions(other.fastLatinOptions) {
    UErrorCode errorCode = U_ZERO_ERROR;
    copyReorderingFrom(other, errorCode);
    if(fastLatinOptions >= 0) {
        uprv_memcpy(fastLatinPrimaries, other.fastLatinPrimaries, sizeof(fastLatinPrimaries));
    }
}

CollationSettings::~CollationSettings() {
    if(reorderCodesCapacity != 0) {
        uprv_free(const_cast<int32_t *>(reorderCodes));
    }
}

UBool
CollationSettings::operator==(const CollationSettings &other) const {
    if(options != other.options) { return FALSE; }
    if((options & ALTERNATE_MASK) != 0 && variableTop != other.variableTop) { return FALSE; }
    if(reorderCodesLength != other.reorderCodesLength) { return FALSE; }
    for(int32_t i = 0; i < reorderCodesLength; ++i) {
        if(reorderCodes[i] != other.reorderCodes[i]) { return FALSE; }
    }
    return TRUE;
}

int32_t
CollationSettings::hashCode() const {
    int32_t h = options << 8;
    if((options & ALTERNATE_MASK) != 0) { h ^= variableTop; }
    h ^= reorderCodesLength;
    for(int32_t i = 0; i < reorderCodesLength; ++i) {
        h ^= (reorderCodes[i] << i);
    }
    return h;
}

void
CollationSettings::resetReordering() {
    // When we turn off reordering, we want to set a NULL permutation
    // rather than a no-op permutation.
    // Keep the memory via reorderCodes and its capacity.
    reorderTable = NULL;
    minHighNoReorder = 0;
    reorderRangesLength = 0;
    reorderCodesLength = 0;
}

void
CollationSettings::aliasReordering(const CollationData &data, const int32_t *codes, int32_t length,
                                   const uint32_t *ranges, int32_t rangesLength,
                                   const uint8_t *table, UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) { return; }
    if(table != NULL &&
            (rangesLength == 0 ?
                    !reorderTableHasSplitBytes(table) :
                    rangesLength >= 2 &&
                    // The first offset must be 0. The last offset must not be 0.
                    (ranges[0] & 0xffff) == 0 && (ranges[rangesLength - 1] & 0xffff) != 0)) {
        // We need to release the memory before setting the alias pointer.
        if(reorderCodesCapacity != 0) {
            uprv_free(const_cast<int32_t *>(reorderCodes));
            reorderCodesCapacity = 0;
        }
        reorderTable = table;
        reorderCodes = codes;
        reorderCodesLength = length;
        // Drop ranges before the first split byte. They are reordered by the table.
        // This then speeds up reordering of the remaining ranges.
        int32_t firstSplitByteRangeIndex = 0;
        while(firstSplitByteRangeIndex < rangesLength &&
                (ranges[firstSplitByteRangeIndex] & 0xff0000) == 0) {
            // The second byte of the primary limit is 0.
            ++firstSplitByteRangeIndex;
        }
        if(firstSplitByteRangeIndex == rangesLength) {
            U_ASSERT(!reorderTableHasSplitBytes(table));
            minHighNoReorder = 0;
            reorderRanges = NULL;
            reorderRangesLength = 0;
        } else {
            U_ASSERT(table[ranges[firstSplitByteRangeIndex] >> 24] == 0);
            minHighNoReorder = ranges[rangesLength - 1] & 0xffff0000;
            reorderRanges = ranges + firstSplitByteRangeIndex;
            reorderRangesLength = rangesLength - firstSplitByteRangeIndex;
        }
        return;
    }
    // Regenerate missing data.
    setReordering(data, codes, length, errorCode);
}

void
CollationSettings::setReordering(const CollationData &data,
                                 const int32_t *codes, int32_t codesLength,
                                 UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) { return; }
    if(codesLength == 0 || (codesLength == 1 && codes[0] == UCOL_REORDER_CODE_NONE)) {
        resetReordering();
        return;
    }
    UVector32 rangesList(errorCode);
    data.makeReorderRanges(codes, codesLength, rangesList, errorCode);
    if(U_FAILURE(errorCode)) { return; }
    int32_t rangesLength = rangesList.size();
    if(rangesLength == 0) {
        resetReordering();
        return;
    }
    const uint32_t *ranges = reinterpret_cast<uint32_t *>(rangesList.getBuffer());
    // ranges[] contains at least two (limit, offset) pairs.
    // The first offset must be 0. The last offset must not be 0.
    // Separators (at the low end) and trailing weights (at the high end)
    // are never reordered.
    U_ASSERT(rangesLength >= 2);
    U_ASSERT((ranges[0] & 0xffff) == 0 && (ranges[rangesLength - 1] & 0xffff) != 0);
    minHighNoReorder = ranges[rangesLength - 1] & 0xffff0000;

    // Write the lead byte permutation table.
    // Set a 0 for each lead byte that has a range boundary in the middle.
    uint8_t table[256];
    int32_t b = 0;
    int32_t firstSplitByteRangeIndex = -1;
    for(int32_t i = 0; i < rangesLength; ++i) {
        uint32_t pair = ranges[i];
        int32_t limit1 = (int32_t)(pair >> 24);
        while(b < limit1) {
            table[b] = (uint8_t)(b + pair);
            ++b;
        }
        // Check the second byte of the limit.
        if((pair & 0xff0000) != 0) {
            table[limit1] = 0;
            b = limit1 + 1;
            if(firstSplitByteRangeIndex < 0) {
                firstSplitByteRangeIndex = i;
            }
        }
    }
    while(b <= 0xff) {
        table[b] = (uint8_t)b;
        ++b;
    }
    if(firstSplitByteRangeIndex < 0) {
        // The lead byte permutation table alone suffices for reordering.
        rangesLength = 0;
    } else {
        // Remove the ranges below the first split byte.
        ranges += firstSplitByteRangeIndex;
        rangesLength -= firstSplitByteRangeIndex;
    }
    setReorderArrays(codes, codesLength, ranges, rangesLength, table, errorCode);
}

void
CollationSettings::setReorderArrays(const int32_t *codes, int32_t codesLength,
                                    const uint32_t *ranges, int32_t rangesLength,
                                    const uint8_t *table, UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) { return; }
    int32_t *ownedCodes;
    int32_t totalLength = codesLength + rangesLength;
    U_ASSERT(totalLength > 0);
    if(totalLength <= reorderCodesCapacity) {
        ownedCodes = const_cast<int32_t *>(reorderCodes);
    } else {
        // Allocate one memory block for the codes, the ranges, and the 16-aligned table.
        int32_t capacity = (totalLength + 3) & ~3;  // round up to a multiple of 4 ints
        ownedCodes = (int32_t *)uprv_malloc(capacity * 4 + 256);
        if(ownedCodes == NULL) {
            resetReordering();
            errorCode = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        if(reorderCodesCapacity != 0) {
            uprv_free(const_cast<int32_t *>(reorderCodes));
        }
        reorderCodes = ownedCodes;
        reorderCodesCapacity = capacity;
    }
    uprv_memcpy(ownedCodes + reorderCodesCapacity, table, 256);
    uprv_memcpy(ownedCodes, codes, codesLength * 4);
    uprv_memcpy(ownedCodes + codesLength, ranges, rangesLength * 4);
    reorderTable = reinterpret_cast<const uint8_t *>(reorderCodes + reorderCodesCapacity);
    reorderCodesLength = codesLength;
    reorderRanges = reinterpret_cast<uint32_t *>(ownedCodes) + codesLength;
    reorderRangesLength = rangesLength;
}

void
CollationSettings::copyReorderingFrom(const CollationSettings &other, UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) { return; }
    if(!other.hasReordering()) {
        resetReordering();
        return;
    }
    minHighNoReorder = other.minHighNoReorder;
    if(other.reorderCodesCapacity == 0) {
        // The reorder arrays are aliased to memory-mapped data.
        reorderTable = other.reorderTable;
        reorderRanges = other.reorderRanges;
        reorderRangesLength = other.reorderRangesLength;
        reorderCodes = other.reorderCodes;
        reorderCodesLength = other.reorderCodesLength;
    } else {
        setReorderArrays(other.reorderCodes, other.reorderCodesLength,
                         other.reorderRanges, other.reorderRangesLength,
                         other.reorderTable, errorCode);
    }
}

UBool
CollationSettings::reorderTableHasSplitBytes(const uint8_t table[256]) {
    U_ASSERT(table[0] == 0);
    for(int32_t i = 1; i < 256; ++i) {
        if(table[i] == 0) {
            return TRUE;
        }
    }
    return FALSE;
}

uint32_t
CollationSettings::reorderEx(uint32_t p) const {
    if(p >= minHighNoReorder) { return p; }
    // Round up p so that its lower 16 bits are >= any offset bits.
    // Then compare q directly with (limit, offset) pairs.
    uint32_t q = p | 0xffff;
    uint32_t r;
    const uint32_t *ranges = reorderRanges;
    while(q >= (r = *ranges)) { ++ranges; }
    return p + (r << 24);
}

void
CollationSettings::setStrength(int32_t value, int32_t defaultOptions, UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) { return; }
    int32_t noStrength = options & ~STRENGTH_MASK;
    switch(value) {
    case UCOL_PRIMARY:
    case UCOL_SECONDARY:
    case UCOL_TERTIARY:
    case UCOL_QUATERNARY:
    case UCOL_IDENTICAL:
        options = noStrength | (value << STRENGTH_SHIFT);
        break;
    case UCOL_DEFAULT:
        options = noStrength | (defaultOptions & STRENGTH_MASK);
        break;
    default:
        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
        break;
    }
}

void
CollationSettings::setFlag(int32_t bit, UColAttributeValue value,
                           int32_t defaultOptions, UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) { return; }
    switch(value) {
    case UCOL_ON:
        options |= bit;
        break;
    case UCOL_OFF:
        options &= ~bit;
        break;
    case UCOL_DEFAULT:
        options = (options & ~bit) | (defaultOptions & bit);
        break;
    default:
        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
        break;
    }
}

void
CollationSettings::setCaseFirst(UColAttributeValue value,
                                int32_t defaultOptions, UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) { return; }
    int32_t noCaseFirst = options & ~CASE_FIRST_AND_UPPER_MASK;
    switch(value) {
    case UCOL_OFF:
        options = noCaseFirst;
        break;
    case UCOL_LOWER_FIRST:
        options = noCaseFirst | CASE_FIRST;
        break;
    case UCOL_UPPER_FIRST:
        options = noCaseFirst | CASE_FIRST_AND_UPPER_MASK;
        break;
    case UCOL_DEFAULT:
        options = noCaseFirst | (defaultOptions & CASE_FIRST_AND_UPPER_MASK);
        break;
    default:
        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
        break;
    }
}

void
CollationSettings::setAlternateHandling(UColAttributeValue value,
                                        int32_t defaultOptions, UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) { return; }
    int32_t noAlternate = options & ~ALTERNATE_MASK;
    switch(value) {
    case UCOL_NON_IGNORABLE:
        options = noAlternate;
        break;
    case UCOL_SHIFTED:
        options = noAlternate | SHIFTED;
        break;
    case UCOL_DEFAULT:
        options = noAlternate | (defaultOptions & ALTERNATE_MASK);
        break;
    default:
        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
        break;
    }
}

void
CollationSettings::setMaxVariable(int32_t value, int32_t defaultOptions, UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) { return; }
    int32_t noMax = options & ~MAX_VARIABLE_MASK;
    switch(value) {
    case MAX_VAR_SPACE:
    case MAX_VAR_PUNCT:
    case MAX_VAR_SYMBOL:
    case MAX_VAR_CURRENCY:
        options = noMax | (value << MAX_VARIABLE_SHIFT);
        break;
    case UCOL_DEFAULT:
        options = noMax | (defaultOptions & MAX_VARIABLE_MASK);
        break;
    default:
        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
        break;
    }
}

U_NAMESPACE_END

#endif  // !UCONFIG_NO_COLLATION
