/*
 * Copyright (C) 2020 Sony Interactive Entertainment Inc.
 * Copyright (C) 2021 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "IntlLocale.h"

#include "IntlDateTimeFormat.h"
#include "IntlObjectInlines.h"
#include "JSCInlines.h"
#include <unicode/ucal.h>
#include <unicode/ucol.h>
#include <unicode/udat.h>
#include <unicode/udatpg.h>
#include <unicode/uloc.h>
#include <unicode/unumsys.h>
#include <wtf/unicode/icu/ICUHelpers.h>

namespace JSC {

const ClassInfo IntlLocale::s_info = { "Object", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(IntlLocale) };

namespace IntlLocaleInternal {
static constexpr bool verbose = false;
}

IntlLocale* IntlLocale::create(VM& vm, Structure* structure)
{
    auto* object = new (NotNull, allocateCell<IntlLocale>(vm.heap)) IntlLocale(vm, structure);
    object->finishCreation(vm);
    return object;
}

Structure* IntlLocale::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
    return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
}

IntlLocale::IntlLocale(VM& vm, Structure* structure)
    : Base(vm, structure)
{
}

void IntlLocale::finishCreation(VM& vm)
{
    Base::finishCreation(vm);
    ASSERT(inherits(vm, info()));
}

template<typename Visitor>
void IntlLocale::visitChildrenImpl(JSCell* cell, Visitor& visitor)
{
    auto* thisObject = jsCast<IntlLocale*>(cell);
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());

    Base::visitChildren(thisObject, visitor);
}

DEFINE_VISIT_CHILDREN(IntlLocale);

class LocaleIDBuilder final {
public:
    bool initialize(const String&);
    CString toCanonical();

    void overrideLanguageScriptRegion(StringView language, StringView script, StringView region);
    void setKeywordValue(ASCIILiteral key, StringView value);

private:
    Vector<char, 32> m_buffer;
};

bool LocaleIDBuilder::initialize(const String& tag)
{
    if (!isStructurallyValidLanguageTag(tag))
        return false;
    ASSERT(tag.isAllASCII());
    m_buffer = localeIDBufferForLanguageTagWithNullTerminator(tag.ascii());
    return m_buffer.size();
}

CString LocaleIDBuilder::toCanonical()
{
    ASSERT(m_buffer.size());

    auto buffer = canonicalizeLocaleIDWithoutNullTerminator(m_buffer.data());
    if (!buffer)
        return CString();

    auto result = canonicalizeUnicodeExtensionsAfterICULocaleCanonicalization(WTFMove(buffer.value()));
    return CString(result.data(), result.size());
}

// Because ICU's C API doesn't have set[Language|Script|Region] functions...
void LocaleIDBuilder::overrideLanguageScriptRegion(StringView language, StringView script, StringView region)
{
    unsigned length = strlen(m_buffer.data());
    ASSERT(length);

    StringView localeIDView { m_buffer.data(), length };

    auto endOfLanguageScriptRegionVariant = localeIDView.find(ULOC_KEYWORD_SEPARATOR);
    if (endOfLanguageScriptRegionVariant == notFound)
        endOfLanguageScriptRegionVariant = length;

    Vector<StringView> subtags;
    for (auto subtag : localeIDView.left(endOfLanguageScriptRegionVariant).splitAllowingEmptyEntries('_'))
        subtags.append(subtag);

    if (!language.isNull())
        subtags[0] = language;

    bool hasScript = subtags.size() > 1 && subtags[1].length() == 4;
    if (!script.isNull()) {
        if (hasScript)
            subtags[1] = script;
        else {
            subtags.insert(1, script);
            hasScript = true;
        }
    }

    if (!region.isNull()) {
        size_t index = hasScript ? 2 : 1;
        bool hasRegion = subtags.size() > index && subtags[index].length() < 4;
        if (hasRegion)
            subtags[index] = region;
        else
            subtags.insert(index, region);
    }

    Vector<char, 32> buffer;
    bool hasAppended = false;
    for (auto subtag : subtags) {
        if (hasAppended)
            buffer.append('_');
        else
            hasAppended = true;

        ASSERT(subtag.isAllASCII());
        if (subtag.is8Bit())
            buffer.append(subtag.characters8(), subtag.length());
        else
            buffer.append(subtag.characters16(), subtag.length());
    }

    if (endOfLanguageScriptRegionVariant != length) {
        auto rest = localeIDView.right(length - endOfLanguageScriptRegionVariant);

        ASSERT(rest.isAllASCII());
        if (rest.is8Bit())
            buffer.append(rest.characters8(), rest.length());
        else
            buffer.append(rest.characters16(), rest.length());
    }

    buffer.append('\0');
    m_buffer.swap(buffer);
}

void LocaleIDBuilder::setKeywordValue(ASCIILiteral key, StringView value)
{
    ASSERT(m_buffer.size());

    ASSERT(value.isAllASCII());
    Vector<char, 32> rawValue(value.length() + 1);
    if (value.is8Bit())
        StringImpl::copyCharacters(reinterpret_cast<LChar*>(rawValue.data()), value.characters8(), value.length());
    else
        StringImpl::copyCharacters(reinterpret_cast<LChar*>(rawValue.data()), value.characters16(), value.length());
    rawValue[value.length()] = '\0';

    UErrorCode status = U_ZERO_ERROR;
    auto length = uloc_setKeywordValue(key.characters(), rawValue.data(), m_buffer.data(), m_buffer.size(), &status);
    // uloc_setKeywordValue does not set U_STRING_NOT_TERMINATED_WARNING.
    if (needsToGrowToProduceBuffer(status)) {
        m_buffer.grow(length + 1);
        status = U_ZERO_ERROR;
        uloc_setKeywordValue(key.characters(), rawValue.data(), m_buffer.data(), length + 1, &status);
    }
    ASSERT(U_SUCCESS(status));
}

String IntlLocale::keywordValue(ASCIILiteral key, bool isBoolean) const
{
    UErrorCode status = U_ZERO_ERROR;
    Vector<char, 32> buffer(32);
    auto bufferLength = uloc_getKeywordValue(m_localeID.data(), key.characters(), buffer.data(), buffer.size(), &status);
    if (needsToGrowToProduceCString(status)) {
        buffer.grow(bufferLength + 1);
        status = U_ZERO_ERROR;
        uloc_getKeywordValue(m_localeID.data(), key.characters(), buffer.data(), buffer.size(), &status);
    }
    ASSERT(U_SUCCESS(status));
    if (isBoolean)
        return String(buffer.data());
    const char* value = uloc_toUnicodeLocaleType(key.characters(), buffer.data());
    if (!value)
        return nullString();
    String result(value);
    if (result == "true"_s)
        return emptyString();
    return result;
}

// https://tc39.es/ecma402/#sec-Intl.Locale
void IntlLocale::initializeLocale(JSGlobalObject* globalObject, JSValue tagValue, JSValue optionsValue)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    String tag = tagValue.inherits<IntlLocale>(vm) ? jsCast<IntlLocale*>(tagValue)->toString() : tagValue.toWTFString(globalObject);
    RETURN_IF_EXCEPTION(scope, void());
    scope.release();
    initializeLocale(globalObject, tag, optionsValue);
}

// https://tc39.es/ecma402/#sec-Intl.Locale
void IntlLocale::initializeLocale(JSGlobalObject* globalObject, const String& tag, JSValue optionsValue)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    JSObject* options = intlCoerceOptionsToObject(globalObject, optionsValue);
    RETURN_IF_EXCEPTION(scope, void());

    LocaleIDBuilder localeID;
    if (!localeID.initialize(tag)) {
        throwRangeError(globalObject, scope, "invalid language tag"_s);
        return;
    }

    String language = intlStringOption(globalObject, options, vm.propertyNames->language, { }, nullptr, nullptr);
    RETURN_IF_EXCEPTION(scope, void());
    if (!language.isNull() && !isUnicodeLanguageSubtag(language)) {
        throwRangeError(globalObject, scope, "language is not a well-formed language value"_s);
        return;
    }

    String script = intlStringOption(globalObject, options, vm.propertyNames->script, { }, nullptr, nullptr);
    RETURN_IF_EXCEPTION(scope, void());
    if (!script.isNull() && !isUnicodeScriptSubtag(script)) {
        throwRangeError(globalObject, scope, "script is not a well-formed script value"_s);
        return;
    }

    String region = intlStringOption(globalObject, options, vm.propertyNames->region, { }, nullptr, nullptr);
    RETURN_IF_EXCEPTION(scope, void());
    if (!region.isNull() && !isUnicodeRegionSubtag(region)) {
        throwRangeError(globalObject, scope, "region is not a well-formed region value"_s);
        return;
    }

    if (!language.isNull() || !script.isNull() || !region.isNull())
        localeID.overrideLanguageScriptRegion(language, script, region);

    String calendar = intlStringOption(globalObject, options, vm.propertyNames->calendar, { }, nullptr, nullptr);
    RETURN_IF_EXCEPTION(scope, void());
    if (!calendar.isNull()) {
        if (!isUnicodeLocaleIdentifierType(calendar)) {
            throwRangeError(globalObject, scope, "calendar is not a well-formed calendar value"_s);
            return;
        }
        localeID.setKeywordValue("calendar"_s, calendar);
    }

    String collation = intlStringOption(globalObject, options, vm.propertyNames->collation, { }, nullptr, nullptr);
    RETURN_IF_EXCEPTION(scope, void());
    if (!collation.isNull()) {
        if (!isUnicodeLocaleIdentifierType(collation)) {
            throwRangeError(globalObject, scope, "collation is not a well-formed collation value"_s);
            return;
        }
        localeID.setKeywordValue("collation"_s, collation);
    }

    String hourCycle = intlStringOption(globalObject, options, vm.propertyNames->hourCycle, { "h11", "h12", "h23", "h24" }, "hourCycle must be \"h11\", \"h12\", \"h23\", or \"h24\"", nullptr);
    RETURN_IF_EXCEPTION(scope, void());
    if (!hourCycle.isNull())
        localeID.setKeywordValue("hours"_s, hourCycle);

    String caseFirst = intlStringOption(globalObject, options, vm.propertyNames->caseFirst, { "upper", "lower", "false" }, "caseFirst must be either \"upper\", \"lower\", or \"false\"", nullptr);
    RETURN_IF_EXCEPTION(scope, void());
    if (!caseFirst.isNull())
        localeID.setKeywordValue("colcasefirst"_s, caseFirst);

    TriState numeric = intlBooleanOption(globalObject, options, vm.propertyNames->numeric);
    RETURN_IF_EXCEPTION(scope, void());
    if (numeric != TriState::Indeterminate)
        localeID.setKeywordValue("colnumeric"_s, numeric == TriState::True ? "yes" : "no");

    String numberingSystem = intlStringOption(globalObject, options, vm.propertyNames->numberingSystem, { }, nullptr, nullptr);
    RETURN_IF_EXCEPTION(scope, void());
    if (!numberingSystem.isNull()) {
        if (!isUnicodeLocaleIdentifierType(numberingSystem)) {
            throwRangeError(globalObject, scope, "numberingSystem is not a well-formed numbering system value"_s);
            return;
        }
        localeID.setKeywordValue("numbers"_s, numberingSystem);
    }

    m_localeID = localeID.toCanonical();
    if (m_localeID.isNull()) {
        throwTypeError(globalObject, scope, "failed to initialize Locale"_s);
        return;
    }
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.maximize
const String& IntlLocale::maximal()
{
    if (m_maximal.isNull()) {
        // ICU has a serious bug that it fails to perform uloc_addLikelySubtags when the input localeID is longer than ULOC_FULLNAME_CAPACITY,
        // and that can be achieved if we add many unicode extensions. While ICU needs to be fixed, we work-around this bug for now: We pass
        // non-keyword part of ICU locale ID and later, concatenate keyword part to the output.
        // Note that ICU locale ID consists of Language, Script, Country (unicode language tag's region.
        // FIXME: ICU tracking bug https://unicode-org.atlassian.net/browse/ICU-21639.
        UErrorCode status = U_ZERO_ERROR;
        Vector<char, 32> buffer(32);
        auto bufferLength = uloc_addLikelySubtags(m_localeID.data(), buffer.data(), buffer.size(), &status);
        if (needsToGrowToProduceCString(status)) {
            buffer.grow(bufferLength + 1);
            status = U_ZERO_ERROR;
            uloc_addLikelySubtags(m_localeID.data(), buffer.data(), buffer.size(), &status);
        }

        if (U_SUCCESS(status))
            m_maximal = languageTagForLocaleID(buffer.data());
        else {
            status = U_ZERO_ERROR;
            Vector<char, 32> baseNameID;
            auto bufferLength = uloc_getBaseName(m_localeID.data(), baseNameID.data(), baseNameID.size(), &status);
            if (needsToGrowToProduceCString(status)) {
                baseNameID.grow(bufferLength + 1);
                status = U_ZERO_ERROR;
                uloc_getBaseName(m_localeID.data(), baseNameID.data(), baseNameID.size(), &status);
            }
            ASSERT(U_SUCCESS(status));

            Vector<char, 32> maximal;
            status = callBufferProducingFunction(uloc_addLikelySubtags, baseNameID.data(), maximal);
            // We fail if,
            // 1. uloc_addLikelySubtags still fails.
            // 2. New maximal locale ID includes newly-added keywords.
            if (!U_SUCCESS(status) || maximal.find(ULOC_KEYWORD_SEPARATOR) != notFound) {
                m_maximal = toString();
                return m_maximal;
            }

            auto endOfLanguageScriptRegionVariant = WTF::find(m_localeID.data(), m_localeID.length(), ULOC_KEYWORD_SEPARATOR);
            if (endOfLanguageScriptRegionVariant != notFound)
                maximal.appendRange(m_localeID.data() + endOfLanguageScriptRegionVariant, m_localeID.data() + m_localeID.length());
            maximal.append('\0');
            m_maximal = languageTagForLocaleID(maximal.data());
        }
    }
    return m_maximal;
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.minimize
const String& IntlLocale::minimal()
{
    if (m_minimal.isNull()) {
        // ICU has a serious bug that it fails to perform uloc_minimizeSubtags when the input localeID is longer than ULOC_FULLNAME_CAPACITY,
        // and that can be achieved if we add many unicode extensions. While ICU needs to be fixed, we work-around this bug for now: We pass
        // non-keyword part of ICU locale ID and later, concatenate keyword part to the output.
        // Note that ICU locale ID consists of Language, Script, Country (unicode language tag's region.
        // FIXME: ICU tracking bug https://unicode-org.atlassian.net/browse/ICU-21639.
        UErrorCode status = U_ZERO_ERROR;
        Vector<char, 32> buffer(32);
        auto bufferLength = uloc_minimizeSubtags(m_localeID.data(), buffer.data(), buffer.size(), &status);
        if (needsToGrowToProduceCString(status)) {
            buffer.grow(bufferLength + 1);
            status = U_ZERO_ERROR;
            uloc_minimizeSubtags(m_localeID.data(), buffer.data(), buffer.size(), &status);
        }

        if (U_SUCCESS(status))
            m_minimal = languageTagForLocaleID(buffer.data());
        else {
            status = U_ZERO_ERROR;
            Vector<char, 32> baseNameID;
            auto bufferLength = uloc_getBaseName(m_localeID.data(), baseNameID.data(), baseNameID.size(), &status);
            if (needsToGrowToProduceCString(status)) {
                baseNameID.grow(bufferLength + 1);
                status = U_ZERO_ERROR;
                uloc_getBaseName(m_localeID.data(), baseNameID.data(), baseNameID.size(), &status);
            }
            ASSERT(U_SUCCESS(status));

            Vector<char, 32> minimal;
            auto status = callBufferProducingFunction(uloc_minimizeSubtags, baseNameID.data(), minimal);
            // We fail if,
            // 1. uloc_minimizeSubtags still fails.
            // 2. New minimal locale ID includes newly-added keywords.
            if (!U_SUCCESS(status) || minimal.find(ULOC_KEYWORD_SEPARATOR) != notFound) {
                m_minimal = toString();
                return m_minimal;
            }

            auto endOfLanguageScriptRegionVariant = WTF::find(m_localeID.data(), m_localeID.length(), ULOC_KEYWORD_SEPARATOR);
            if (endOfLanguageScriptRegionVariant != notFound)
                minimal.appendRange(m_localeID.data() + endOfLanguageScriptRegionVariant, m_localeID.data() + m_localeID.length());
            minimal.append('\0');
            m_minimal = languageTagForLocaleID(minimal.data());
        }
    }
    return m_minimal;
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString
const String& IntlLocale::toString()
{
    if (m_fullString.isNull())
        m_fullString = languageTagForLocaleID(m_localeID.data());
    return m_fullString;
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.baseName
const String& IntlLocale::baseName()
{
    if (m_baseName.isNull()) {
        UErrorCode status = U_ZERO_ERROR;
        Vector<char, 32> buffer(32);
        auto bufferLength = uloc_getBaseName(m_localeID.data(), buffer.data(), buffer.size(), &status);
        if (needsToGrowToProduceCString(status)) {
            buffer.grow(bufferLength + 1);
            status = U_ZERO_ERROR;
            uloc_getBaseName(m_localeID.data(), buffer.data(), buffer.size(), &status);
        }
        ASSERT(U_SUCCESS(status));

        m_baseName = languageTagForLocaleID(buffer.data());
    }
    return m_baseName;
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.language
const String& IntlLocale::language()
{
    if (m_language.isNull()) {
        Vector<char, 8> buffer;
        auto status = callBufferProducingFunction(uloc_getLanguage, m_localeID.data(), buffer);
        ASSERT_UNUSED(status, U_SUCCESS(status));
        m_language = String(buffer.data(), buffer.size());
    }
    return m_language;
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.script
const String& IntlLocale::script()
{
    if (m_script.isNull()) {
        Vector<char, 4> buffer;
        auto status = callBufferProducingFunction(uloc_getScript, m_localeID.data(), buffer);
        ASSERT_UNUSED(status, U_SUCCESS(status));
        m_script = String(buffer.data(), buffer.size());
    }
    return m_script;
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.region
const String& IntlLocale::region()
{
    if (m_region.isNull()) {
        Vector<char, 3> buffer;
        auto status = callBufferProducingFunction(uloc_getCountry, m_localeID.data(), buffer);
        ASSERT_UNUSED(status, U_SUCCESS(status));
        m_region = String(buffer.data(), buffer.size());
    }
    return m_region;
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.calendar
const String& IntlLocale::calendar()
{
    if (!m_calendar)
        m_calendar = keywordValue("calendar"_s);
    return m_calendar.value();
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.caseFirst
const String& IntlLocale::caseFirst()
{
    if (!m_caseFirst)
        m_caseFirst = keywordValue("colcasefirst"_s);
    return m_caseFirst.value();
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.collation
const String& IntlLocale::collation()
{
    if (!m_collation)
        m_collation = keywordValue("collation"_s);
    return m_collation.value();
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.hourCycle
const String& IntlLocale::hourCycle()
{
    if (!m_hourCycle)
        m_hourCycle = keywordValue("hours"_s);
    return m_hourCycle.value();
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numberingSystem
const String& IntlLocale::numberingSystem()
{
    if (!m_numberingSystem)
        m_numberingSystem = keywordValue("numbers"_s);
    return m_numberingSystem.value();
}

// https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numeric
TriState IntlLocale::numeric()
{
    constexpr bool isBoolean = true;
    if (m_numeric == TriState::Indeterminate)
        m_numeric = triState(keywordValue("colnumeric"_s, isBoolean) == "yes"_s);
    return m_numeric;
}

JSArray* IntlLocale::calendars(JSGlobalObject* globalObject)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    Vector<String, 1> elements;

    String preferred = calendar();
    if (!preferred.isEmpty()) {
        elements.append(WTFMove(preferred));
        RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
    }

    UErrorCode status = U_ZERO_ERROR;
    constexpr bool commonlyUsed = true;
    auto calendars = std::unique_ptr<UEnumeration, ICUDeleter<uenum_close>>(ucal_getKeywordValuesForLocale("calendar", m_localeID.data(), commonlyUsed, &status));
    if (!U_SUCCESS(status)) {
        throwTypeError(globalObject, scope, "invalid locale"_s);
        return nullptr;
    }

    const char* pointer;
    int32_t length = 0;
    while ((pointer = uenum_next(calendars.get(), &length, &status)) && U_SUCCESS(status)) {
        String calendar(pointer, length);
        if (auto mapped = mapICUCalendarKeywordToBCP47(calendar))
            elements.append(WTFMove(mapped.value()));
        else
            elements.append(WTFMove(calendar));
    }
    if (!U_SUCCESS(status)) {
        throwTypeError(globalObject, scope, "invalid locale"_s);
        return nullptr;
    }

    RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
}

JSArray* IntlLocale::collations(JSGlobalObject* globalObject)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    Vector<String, 1> elements;

    String preferred = collation();
    if (!preferred.isEmpty()) {
        elements.append(WTFMove(preferred));
        RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
    }

    UErrorCode status = U_ZERO_ERROR;
    constexpr bool commonlyUsed = true;
    auto enumeration = std::unique_ptr<UEnumeration, ICUDeleter<uenum_close>>(ucol_getKeywordValuesForLocale("collation", m_localeID.data(), commonlyUsed, &status));
    if (!U_SUCCESS(status)) {
        throwTypeError(globalObject, scope, "invalid locale"_s);
        return nullptr;
    }

    const char* pointer;
    int32_t length = 0;
    while ((pointer = uenum_next(enumeration.get(), &length, &status)) && U_SUCCESS(status)) {
        String collation(pointer, length);
        // 1.1.3 step 4, The values "standard" and "search" must be excluded from list.
        if (collation == "standard"_s || collation == "search"_s)
            continue;
        if (auto mapped = mapICUCollationKeywordToBCP47(collation))
            elements.append(WTFMove(mapped.value()));
        else
            elements.append(WTFMove(collation));
    }
    if (!U_SUCCESS(status)) {
        throwTypeError(globalObject, scope, "invalid locale"_s);
        return nullptr;
    }

    RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
}

JSArray* IntlLocale::hourCycles(JSGlobalObject* globalObject)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    Vector<String, 1> elements;

    String preferred = hourCycle();
    if (!preferred.isEmpty()) {
        elements.append(WTFMove(preferred));
        RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
    }

    UErrorCode status = U_ZERO_ERROR;
    auto generator = std::unique_ptr<UDateTimePatternGenerator, ICUDeleter<udatpg_close>>(udatpg_open(m_localeID.data(), &status));
    if (U_FAILURE(status))
        return nullptr;

    // Use "j" skeleton and parse pattern to retrieve the configured hour-cycle information.
    constexpr const UChar skeleton[] = { 'j', 0 };
    Vector<UChar, 32> pattern;
    status = callBufferProducingFunction(udatpg_getBestPatternWithOptions, generator.get(), skeleton, 1, UDATPG_MATCH_HOUR_FIELD_LENGTH, pattern);
    if (!U_SUCCESS(status)) {
        throwTypeError(globalObject, scope, "invalid locale"_s);
        return nullptr;
    }

    dataLogLnIf(IntlLocaleInternal::verbose, "pattern:(", StringView(pattern.data(), pattern.size()), ")");

    switch (IntlDateTimeFormat::hourCycleFromPattern(pattern)) {
    case IntlDateTimeFormat::HourCycle::None:
        break;
    case IntlDateTimeFormat::HourCycle::H11: {
        elements.append("h11"_s);
        RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
    }
    case IntlDateTimeFormat::HourCycle::H12: {
        elements.append("h12"_s);
        RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
    }
    case IntlDateTimeFormat::HourCycle::H23: {
        elements.append("h23"_s);
        RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
    }
    case IntlDateTimeFormat::HourCycle::H24: {
        elements.append("h24"_s);
        RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
    }
    }

    RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
}

JSArray* IntlLocale::numberingSystems(JSGlobalObject* globalObject)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    Vector<String, 1> elements;
    String preferred = numberingSystem();
    if (!preferred.isEmpty()) {
        elements.append(WTFMove(preferred));
        RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
    }

    UErrorCode status = U_ZERO_ERROR;
    auto numberingSystem = std::unique_ptr<UNumberingSystem, ICUDeleter<unumsys_close>>(unumsys_open(m_localeID.data(), &status));
    if (!U_SUCCESS(status)) {
        throwTypeError(globalObject, scope, "invalid locale"_s);
        return nullptr;
    }
    elements.append(unumsys_getName(numberingSystem.get()));

    RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
}

JSValue IntlLocale::timeZones(JSGlobalObject* globalObject)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    Vector<String, 1> elements;

    // 11.6-3 Let region be the substring of locale corresponding to the unicode_region_subtag production of the unicode_language_id.
    String region = this->region();
    if (region.isEmpty())
        return jsUndefined();

    UErrorCode status = U_ZERO_ERROR;
    auto enumeration = std::unique_ptr<UEnumeration, ICUDeleter<uenum_close>>(ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, region.utf8().data(), nullptr, &status));
    if (!U_SUCCESS(status)) {
        throwTypeError(globalObject, scope, "invalid locale"_s);
        return { };
    }

    int32_t length;
    const char* collation;
    while ((collation = uenum_next(enumeration.get(), &length, &status)) && U_SUCCESS(status))
        elements.constructAndAppend(collation, length);
    if (!U_SUCCESS(status)) {
        throwTypeError(globalObject, scope, "invalid locale"_s);
        return { };
    }

    RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
}

JSObject* IntlLocale::textInfo(JSGlobalObject* globalObject)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    UErrorCode status = U_ZERO_ERROR;
    ULayoutType layout = uloc_getCharacterOrientation(m_localeID.data(), &status);
    if (!U_SUCCESS(status)) {
        throwTypeError(globalObject, scope, "invalid locale"_s);
        return nullptr;
    }

    JSString* layoutString = nullptr;
    switch (layout) {
    default:
    case ULOC_LAYOUT_LTR:
        layoutString = jsString(vm, "ltr"_s);
        break;
    case ULOC_LAYOUT_RTL:
        layoutString = jsString(vm, "rtl"_s);
        break;
    case ULOC_LAYOUT_TTB:
        layoutString = jsString(vm, "ttb"_s);
        break;
    case ULOC_LAYOUT_BTT:
        layoutString = jsString(vm, "btt"_s);
        break;
    }

    JSObject* result = constructEmptyObject(globalObject);
    result->putDirect(vm, Identifier::fromString(vm, "direction"), layoutString);
    return result;
}

JSObject* IntlLocale::weekInfo(JSGlobalObject* globalObject)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    UErrorCode status = U_ZERO_ERROR;
    auto calendar = std::unique_ptr<UCalendar, ICUDeleter<ucal_close>>(ucal_open(nullptr, 0, m_localeID.data(), UCAL_DEFAULT, &status));
    if (!U_SUCCESS(status)) {
        throwTypeError(globalObject, scope, "invalid locale"_s);
        return nullptr;
    }

    int32_t firstDayOfWeek = ucal_getAttribute(calendar.get(), UCAL_FIRST_DAY_OF_WEEK);
    int32_t minimalDays = ucal_getAttribute(calendar.get(), UCAL_MINIMAL_DAYS_IN_FIRST_WEEK);

    auto canonicalizeDayOfWeekType = [](UCalendarWeekdayType type) {
        switch (type) {
        // UCAL_WEEKEND_ONSET is a day that starts as a weekday and transitions to the weekend. It means this is WeekDay.
        case UCAL_WEEKEND_ONSET:
        case UCAL_WEEKDAY:
            return UCAL_WEEKDAY;
        // UCAL_WEEKEND_CEASE is a day that starts as the weekend and transitions to a weekday. It means this is WeekEnd.
        case UCAL_WEEKEND_CEASE:
        case UCAL_WEEKEND:
            return UCAL_WEEKEND;
        default:
            return UCAL_WEEKEND;
        }
    };

    auto convertMondayBasedDayToUCalendarDaysOfWeek = [](int32_t day) -> UCalendarDaysOfWeek {
        // Convert from
        //     Monday => 1
        //     Sunday => 7
        // to
        //     Sunday => 1
        //     Saturday => 7
        static_assert(UCAL_SUNDAY == 1);
        static_assert(UCAL_SATURDAY == 7);
        if (day == 7)
            return UCAL_SUNDAY;
        return static_cast<UCalendarDaysOfWeek>(day + 1);
    };

    auto convertUCalendarDaysOfWeekToMondayBasedDay = [](int32_t day) -> int32_t {
        // Convert from
        //     Sunday => 1
        //     Saturday => 7
        // to
        //     Monday => 1
        //     Sunday => 7
        if (day == UCAL_SUNDAY)
            return 7;
        return day - 1;
    };

    Vector<int32_t, 7> weekend;
    for (int32_t day = 1; day <= 7; ++day) {
        UCalendarWeekdayType type = canonicalizeDayOfWeekType(ucal_getDayOfWeekType(calendar.get(), convertMondayBasedDayToUCalendarDaysOfWeek(day), &status));
        if (!U_SUCCESS(status)) {
            throwTypeError(globalObject, scope, "invalid locale"_s);
            return nullptr;
        }
        switch (type) {
        case UCAL_WEEKDAY:
            break;
        case UCAL_WEEKEND:
            weekend.append(day);
            break;
        default:
            ASSERT_NOT_REACHED();
            break;
        }
    }

    auto* weekendArray = createArrayFromIntVector(globalObject, WTFMove(weekend));
    RETURN_IF_EXCEPTION(scope, { });

    JSObject* result = constructEmptyObject(globalObject);
    result->putDirect(vm, Identifier::fromString(vm, "firstDay"), jsNumber(convertUCalendarDaysOfWeekToMondayBasedDay(firstDayOfWeek)));
    result->putDirect(vm, Identifier::fromString(vm, "weekend"), weekendArray);
    result->putDirect(vm, Identifier::fromString(vm, "minimalDays"), jsNumber(minimalDays));
    return result;
}

} // namespace JSC
