// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
* 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
