// © 2019 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html

#include <utility>

#include "bytesinkutil.h"  // CharStringByteSink
#include "charstr.h"
#include "cstring.h"
#include "ulocimp.h"
#include "unicode/localebuilder.h"
#include "unicode/locid.h"

U_NAMESPACE_BEGIN

#define UPRV_ISDIGIT(c) (((c) >= '0') && ((c) <= '9'))
#define UPRV_ISALPHANUM(c) (uprv_isASCIILetter(c) || UPRV_ISDIGIT(c) )

const char* kAttributeKey = "attribute";

static bool _isExtensionSubtags(char key, const char* s, int32_t len) {
    switch (uprv_tolower(key)) {
        case 'u':
            return ultag_isUnicodeExtensionSubtags(s, len);
        case 't':
            return ultag_isTransformedExtensionSubtags(s, len);
        case 'x':
            return ultag_isPrivateuseValueSubtags(s, len);
        default:
            return ultag_isExtensionSubtags(s, len);
    }
}

LocaleBuilder::LocaleBuilder() : UObject(), status_(U_ZERO_ERROR), language_(),
    script_(), region_(), variant_(nullptr), extensions_(nullptr)
{
    language_[0] = 0;
    script_[0] = 0;
    region_[0] = 0;
}

LocaleBuilder::~LocaleBuilder()
{
    delete variant_;
    delete extensions_;
}

LocaleBuilder& LocaleBuilder::setLocale(const Locale& locale)
{
    clear();
    setLanguage(locale.getLanguage());
    setScript(locale.getScript());
    setRegion(locale.getCountry());
    setVariant(locale.getVariant());
    extensions_ = locale.clone();
    if (extensions_ == nullptr) {
        status_ = U_MEMORY_ALLOCATION_ERROR;
    }
    return *this;
}

LocaleBuilder& LocaleBuilder::setLanguageTag(StringPiece tag)
{
    Locale l = Locale::forLanguageTag(tag, status_);
    if (U_FAILURE(status_)) { return *this; }
    // Because setLocale will reset status_ we need to return
    // first if we have error in forLanguageTag.
    setLocale(l);
    return *this;
}

static void setField(StringPiece input, char* dest, UErrorCode& errorCode,
                     UBool (*test)(const char*, int32_t)) {
    if (U_FAILURE(errorCode)) { return; }
    if (input.empty()) {
        dest[0] = '\0';
    } else if (test(input.data(), input.length())) {
        uprv_memcpy(dest, input.data(), input.length());
        dest[input.length()] = '\0';
    } else {
        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
    }
}

LocaleBuilder& LocaleBuilder::setLanguage(StringPiece language)
{
    setField(language, language_, status_, &ultag_isLanguageSubtag);
    return *this;
}

LocaleBuilder& LocaleBuilder::setScript(StringPiece script)
{
    setField(script, script_, status_, &ultag_isScriptSubtag);
    return *this;
}

LocaleBuilder& LocaleBuilder::setRegion(StringPiece region)
{
    setField(region, region_, status_, &ultag_isRegionSubtag);
    return *this;
}

static void transform(char* data, int32_t len) {
    for (int32_t i = 0; i < len; i++, data++) {
        if (*data == '_') {
            *data = '-';
        } else {
            *data = uprv_tolower(*data);
        }
    }
}

LocaleBuilder& LocaleBuilder::setVariant(StringPiece variant)
{
    if (U_FAILURE(status_)) { return *this; }
    if (variant.empty()) {
        delete variant_;
        variant_ = nullptr;
        return *this;
    }
    CharString* new_variant = new CharString(variant, status_);
    if (U_FAILURE(status_)) { return *this; }
    if (new_variant == nullptr) {
        status_ = U_MEMORY_ALLOCATION_ERROR;
        return *this;
    }
    transform(new_variant->data(), new_variant->length());
    if (!ultag_isVariantSubtags(new_variant->data(), new_variant->length())) {
        delete new_variant;
        status_ = U_ILLEGAL_ARGUMENT_ERROR;
        return *this;
    }
    delete variant_;
    variant_ = new_variant;
    return *this;
}

static bool
_isKeywordValue(const char* key, const char* value, int32_t value_len)
{
    if (key[1] == '\0') {
        // one char key
        return (UPRV_ISALPHANUM(uprv_tolower(key[0])) &&
                _isExtensionSubtags(key[0], value, value_len));
    } else if (uprv_strcmp(key, kAttributeKey) == 0) {
        // unicode attributes
        return ultag_isUnicodeLocaleAttributes(value, value_len);
    }
    // otherwise: unicode extension value
    // We need to convert from legacy key/value to unicode
    // key/value
    const char* unicode_locale_key = uloc_toUnicodeLocaleKey(key);
    const char* unicode_locale_type = uloc_toUnicodeLocaleType(key, value);

    return unicode_locale_key && unicode_locale_type &&
           ultag_isUnicodeLocaleKey(unicode_locale_key, -1) &&
           ultag_isUnicodeLocaleType(unicode_locale_type, -1);
}

static void
_copyExtensions(const Locale& from, icu::StringEnumeration *keywords,
                Locale& to, bool validate, UErrorCode& errorCode)
{
    if (U_FAILURE(errorCode)) { return; }
    LocalPointer<icu::StringEnumeration> ownedKeywords;
    if (keywords == nullptr) {
        ownedKeywords.adoptInstead(from.createKeywords(errorCode));
        if (U_FAILURE(errorCode) || ownedKeywords.isNull()) { return; }
        keywords = ownedKeywords.getAlias();
    }
    const char* key;
    while ((key = keywords->next(nullptr, errorCode)) != nullptr) {
        CharString value;
        CharStringByteSink sink(&value);
        from.getKeywordValue(key, sink, errorCode);
        if (U_FAILURE(errorCode)) { return; }
        if (uprv_strcmp(key, kAttributeKey) == 0) {
            transform(value.data(), value.length());
        }
        if (validate &&
            !_isKeywordValue(key, value.data(), value.length())) {
            errorCode = U_ILLEGAL_ARGUMENT_ERROR;
            return;
        }
        to.setKeywordValue(key, value.data(), errorCode);
        if (U_FAILURE(errorCode)) { return; }
    }
}

void static
_clearUAttributesAndKeyType(Locale& locale, UErrorCode& errorCode)
{
    // Clear Unicode attributes
    locale.setKeywordValue(kAttributeKey, "", errorCode);

    // Clear all Unicode keyword values
    LocalPointer<icu::StringEnumeration> iter(locale.createUnicodeKeywords(errorCode));
    if (U_FAILURE(errorCode) || iter.isNull()) { return; }
    const char* key;
    while ((key = iter->next(nullptr, errorCode)) != nullptr) {
        locale.setUnicodeKeywordValue(key, nullptr, errorCode);
    }
}

static void
_setUnicodeExtensions(Locale& locale, const CharString& value, UErrorCode& errorCode)
{
    // Add the unicode extensions to extensions_
    CharString locale_str("und-u-", errorCode);
    locale_str.append(value, errorCode);
    _copyExtensions(
        Locale::forLanguageTag(locale_str.data(), errorCode), nullptr,
        locale, false, errorCode);
}

LocaleBuilder& LocaleBuilder::setExtension(char key, StringPiece value)
{
    if (U_FAILURE(status_)) { return *this; }
    if (!UPRV_ISALPHANUM(key)) {
        status_ = U_ILLEGAL_ARGUMENT_ERROR;
        return *this;
    }
    CharString value_str(value, status_);
    if (U_FAILURE(status_)) { return *this; }
    transform(value_str.data(), value_str.length());
    if (!value_str.isEmpty() &&
            !_isExtensionSubtags(key, value_str.data(), value_str.length())) {
        status_ = U_ILLEGAL_ARGUMENT_ERROR;
        return *this;
    }
    if (extensions_ == nullptr) {
        extensions_ = Locale::getRoot().clone();
        if (extensions_ == nullptr) {
            status_ = U_MEMORY_ALLOCATION_ERROR;
            return *this;
        }
    }
    if (uprv_tolower(key) != 'u') {
        // for t, x and others extension.
        extensions_->setKeywordValue(StringPiece(&key, 1), value_str.data(),
                                     status_);
        return *this;
    }
    _clearUAttributesAndKeyType(*extensions_, status_);
    if (U_FAILURE(status_)) { return *this; }
    if (!value.empty()) {
        _setUnicodeExtensions(*extensions_, value_str, status_);
    }
    return *this;
}

LocaleBuilder& LocaleBuilder::setUnicodeLocaleKeyword(
      StringPiece key, StringPiece type)
{
    if (U_FAILURE(status_)) { return *this; }
    if (!ultag_isUnicodeLocaleKey(key.data(), key.length()) ||
            (!type.empty() &&
                 !ultag_isUnicodeLocaleType(type.data(), type.length()))) {
      status_ = U_ILLEGAL_ARGUMENT_ERROR;
      return *this;
    }
    if (extensions_ == nullptr) {
        extensions_ = Locale::getRoot().clone();
        if (extensions_ == nullptr) {
            status_ = U_MEMORY_ALLOCATION_ERROR;
            return *this;
        }
    }
    extensions_->setUnicodeKeywordValue(key, type, status_);
    return *this;
}

LocaleBuilder& LocaleBuilder::addUnicodeLocaleAttribute(
    StringPiece value)
{
    CharString value_str(value, status_);
    if (U_FAILURE(status_)) { return *this; }
    transform(value_str.data(), value_str.length());
    if (!ultag_isUnicodeLocaleAttribute(value_str.data(), value_str.length())) {
        status_ = U_ILLEGAL_ARGUMENT_ERROR;
        return *this;
    }
    if (extensions_ == nullptr) {
        extensions_ = Locale::getRoot().clone();
        if (extensions_ == nullptr) {
            status_ = U_MEMORY_ALLOCATION_ERROR;
            return *this;
        }
        extensions_->setKeywordValue(kAttributeKey, value_str.data(), status_);
        return *this;
    }

    CharString attributes;
    CharStringByteSink sink(&attributes);
    UErrorCode localErrorCode = U_ZERO_ERROR;
    extensions_->getKeywordValue(kAttributeKey, sink, localErrorCode);
    if (U_FAILURE(localErrorCode)) {
        CharString new_attributes(value_str.data(), status_);
        // No attributes, set the attribute.
        extensions_->setKeywordValue(kAttributeKey, new_attributes.data(), status_);
        return *this;
    }

    transform(attributes.data(),attributes.length());
    const char* start = attributes.data();
    const char* limit = attributes.data() + attributes.length();
    CharString new_attributes;
    bool inserted = false;
    while (start < limit) {
        if (!inserted) {
            int cmp = uprv_strcmp(start, value_str.data());
            if (cmp == 0) { return *this; }  // Found it in attributes: Just return
            if (cmp > 0) {
                if (!new_attributes.isEmpty()) new_attributes.append('_', status_);
                new_attributes.append(value_str.data(), status_);
                inserted = true;
            }
        }
        if (!new_attributes.isEmpty()) {
            new_attributes.append('_', status_);
        }
        new_attributes.append(start, status_);
        start += uprv_strlen(start) + 1;
    }
    if (!inserted) {
        if (!new_attributes.isEmpty()) {
            new_attributes.append('_', status_);
        }
        new_attributes.append(value_str.data(), status_);
    }
    // Not yet in the attributes, set the attribute.
    extensions_->setKeywordValue(kAttributeKey, new_attributes.data(), status_);
    return *this;
}

LocaleBuilder& LocaleBuilder::removeUnicodeLocaleAttribute(
    StringPiece value)
{
    CharString value_str(value, status_);
    if (U_FAILURE(status_)) { return *this; }
    transform(value_str.data(), value_str.length());
    if (!ultag_isUnicodeLocaleAttribute(value_str.data(), value_str.length())) {
        status_ = U_ILLEGAL_ARGUMENT_ERROR;
        return *this;
    }
    if (extensions_ == nullptr) { return *this; }
    UErrorCode localErrorCode = U_ZERO_ERROR;
    CharString attributes;
    CharStringByteSink sink(&attributes);
    extensions_->getKeywordValue(kAttributeKey, sink, localErrorCode);
    // get failure, just return
    if (U_FAILURE(localErrorCode)) { return *this; }
    // Do not have any attributes, just return.
    if (attributes.isEmpty()) { return *this; }

    char* p = attributes.data();
    // Replace null terminiator in place for _ and - so later
    // we can use uprv_strcmp to compare.
    for (int32_t i = 0; i < attributes.length(); i++, p++) {
        *p = (*p == '_' || *p == '-') ? '\0' : uprv_tolower(*p);
    }

    const char* start = attributes.data();
    const char* limit = attributes.data() + attributes.length();
    CharString new_attributes;
    bool found = false;
    while (start < limit) {
        if (uprv_strcmp(start, value_str.data()) == 0) {
            found = true;
        } else {
            if (!new_attributes.isEmpty()) {
                new_attributes.append('_', status_);
            }
            new_attributes.append(start, status_);
        }
        start += uprv_strlen(start) + 1;
    }
    // Found the value in attributes, set the attribute.
    if (found) {
        extensions_->setKeywordValue(kAttributeKey, new_attributes.data(), status_);
    }
    return *this;
}

LocaleBuilder& LocaleBuilder::clear()
{
    status_ = U_ZERO_ERROR;
    language_[0] = 0;
    script_[0] = 0;
    region_[0] = 0;
    delete variant_;
    variant_ = nullptr;
    clearExtensions();
    return *this;
}

LocaleBuilder& LocaleBuilder::clearExtensions()
{
    delete extensions_;
    extensions_ = nullptr;
    return *this;
}

Locale makeBogusLocale() {
  Locale bogus;
  bogus.setToBogus();
  return bogus;
}

void LocaleBuilder::copyExtensionsFrom(const Locale& src, UErrorCode& errorCode)
{
    if (U_FAILURE(errorCode)) { return; }
    LocalPointer<icu::StringEnumeration> keywords(src.createKeywords(errorCode));
    if (U_FAILURE(errorCode) || keywords.isNull() || keywords->count(errorCode) == 0) {
        // Error, or no extensions to copy.
        return;
    }
    if (extensions_ == nullptr) {
        extensions_ = Locale::getRoot().clone();
        if (extensions_ == nullptr) {
            status_ = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
    }
    _copyExtensions(src, keywords.getAlias(), *extensions_, false, errorCode);
}

Locale LocaleBuilder::build(UErrorCode& errorCode)
{
    if (U_FAILURE(errorCode)) {
        return makeBogusLocale();
    }
    if (U_FAILURE(status_)) {
        errorCode = status_;
        return makeBogusLocale();
    }
    CharString locale_str(language_, errorCode);
    if (uprv_strlen(script_) > 0) {
        locale_str.append('-', errorCode).append(StringPiece(script_), errorCode);
    }
    if (uprv_strlen(region_) > 0) {
        locale_str.append('-', errorCode).append(StringPiece(region_), errorCode);
    }
    if (variant_ != nullptr) {
        locale_str.append('-', errorCode).append(StringPiece(variant_->data()), errorCode);
    }
    if (U_FAILURE(errorCode)) {
        return makeBogusLocale();
    }
    Locale product(locale_str.data());
    if (extensions_ != nullptr) {
        _copyExtensions(*extensions_, nullptr, product, true, errorCode);
    }
    if (U_FAILURE(errorCode)) {
        return makeBogusLocale();
    }
    return product;
}

UBool LocaleBuilder::copyErrorTo(UErrorCode &outErrorCode) const {
    if (U_FAILURE(outErrorCode)) {
        // Do not overwrite the older error code
        return TRUE;
    }
    outErrorCode = status_;
    return U_FAILURE(outErrorCode);
}

U_NAMESPACE_END
