/*
 * Copyright (C) 2016 Yusuke Suzuki <yusuke.suzuki@sslab.ics.keio.ac.jp>
 * Copyright (C) 2016 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.
 */

#pragma once

#include "BuiltinNames.h"
#include "IntlObject.h"
#include "JSBoundFunction.h"
#include "JSObject.h"
#include "ObjectConstructor.h"
#include <unicode/ucol.h>

namespace JSC {

template<typename StringType>
static constexpr uint32_t computeTwoCharacters16Code(const StringType& string)
{
    return static_cast<uint16_t>(string.characterAt(0)) | (static_cast<uint32_t>(static_cast<uint16_t>(string.characterAt(1))) << 16);
}

template<typename Predicate> String bestAvailableLocale(const String& locale, Predicate predicate)
{
    // BestAvailableLocale (availableLocales, locale)
    // https://tc39.github.io/ecma402/#sec-bestavailablelocale

    String candidate = locale;
    while (!candidate.isEmpty()) {
        if (predicate(candidate))
            return candidate;

        size_t pos = candidate.reverseFind('-');
        if (pos == notFound)
            return String();

        if (pos >= 2 && candidate[pos - 2] == '-')
            pos -= 2;

        candidate = candidate.substring(0, pos);
    }

    return String();
}

template<typename Constructor, typename Factory>
JSValue constructIntlInstanceWithWorkaroundForLegacyIntlConstructor(JSGlobalObject* globalObject, JSValue thisValue, Constructor* callee, Factory factory)
{
    // FIXME: Workaround to provide compatibility with ECMA-402 1.0 call/apply patterns.
    // https://bugs.webkit.org/show_bug.cgi?id=153679
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    auto* instance = factory(vm);
    RETURN_IF_EXCEPTION(scope, JSValue());

    if (thisValue.isObject()) {
        JSObject* thisObject = asObject(thisValue);
        ASSERT(!callee->template inherits<JSBoundFunction>(vm));
        JSValue prototype = callee->getDirect(vm, vm.propertyNames->prototype); // Passed constructors always have `prototype` which cannot be deleted.
        ASSERT(prototype);
        bool hasInstance = JSObject::defaultHasInstance(globalObject, thisObject, prototype);
        RETURN_IF_EXCEPTION(scope, JSValue());
        if (hasInstance) {
            PropertyDescriptor descriptor(instance, PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete);
            scope.release();
            thisObject->methodTable(vm)->defineOwnProperty(thisObject, globalObject, vm.propertyNames->builtinNames().intlLegacyConstructedSymbol(), descriptor, true);
            return thisObject;
        }
    }
    return instance;
}

template<typename InstanceType>
InstanceType* unwrapForLegacyIntlConstructor(JSGlobalObject* globalObject, JSValue thisValue, JSObject* constructor)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    JSObject* thisObject = jsDynamicCast<JSObject*>(vm, thisValue);
    if (UNLIKELY(!thisObject))
        return nullptr;

    auto* instance = jsDynamicCast<InstanceType*>(vm, thisObject);
    if (LIKELY(instance))
        return instance;

    ASSERT(!constructor->template inherits<JSBoundFunction>(vm));
    JSValue prototype = constructor->getDirect(vm, vm.propertyNames->prototype); // Passed constructors always have `prototype` which cannot be deleted.
    ASSERT(prototype);
    bool hasInstance = JSObject::defaultHasInstance(globalObject, thisObject, prototype);
    RETURN_IF_EXCEPTION(scope, nullptr);
    if (!hasInstance)
        return nullptr;

    JSValue value = thisObject->get(globalObject, vm.propertyNames->builtinNames().intlLegacyConstructedSymbol());
    RETURN_IF_EXCEPTION(scope, nullptr);
    return jsDynamicCast<InstanceType*>(vm, value);
}

template<typename ResultType>
ResultType intlOption(JSGlobalObject* globalObject, JSObject* options, PropertyName property, std::initializer_list<std::pair<ASCIILiteral, ResultType>> values, ASCIILiteral notFoundMessage, ResultType fallback)
{
    // GetOption (options, property, type="string", values, fallback)
    // https://tc39.github.io/ecma402/#sec-getoption

    ASSERT(values.size() > 0);

    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (!options)
        return fallback;

    JSValue value = options->get(globalObject, property);
    RETURN_IF_EXCEPTION(scope, { });

    if (!value.isUndefined()) {
        String stringValue = value.toWTFString(globalObject);
        RETURN_IF_EXCEPTION(scope, { });

        for (const auto& entry : values) {
            if (entry.first == stringValue)
                return entry.second;
        }
        throwException(globalObject, scope, createRangeError(globalObject, notFoundMessage));
        return { };
    }

    return fallback;
}

template<typename ResultType>
ResultType intlStringOrBooleanOption(JSGlobalObject* globalObject, JSObject* options, PropertyName property, ResultType trueValue, ResultType falsyValue, std::initializer_list<std::pair<ASCIILiteral, ResultType>> values, ASCIILiteral notFoundMessage, ResultType fallback)
{
    // https://tc39.es/proposal-intl-numberformat-v3/out/negotiation/diff.html#sec-getstringorbooleanoption

    ASSERT(values.size() > 0);

    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (!options)
        return fallback;

    JSValue value = options->get(globalObject, property);
    RETURN_IF_EXCEPTION(scope, { });

    if (!value.isUndefined()) {
        if (value.isBoolean() && value.asBoolean())
            return trueValue;

        bool valueBoolean = value.toBoolean(globalObject);
        RETURN_IF_EXCEPTION(scope, { });

        if (!valueBoolean)
            return falsyValue;

        String stringValue = value.toWTFString(globalObject);
        RETURN_IF_EXCEPTION(scope, { });

        for (const auto& entry : values) {
            if (entry.first == stringValue)
                return entry.second;
        }
        throwException(globalObject, scope, createRangeError(globalObject, notFoundMessage));
        return { };
    }

    return fallback;
}

ALWAYS_INLINE bool canUseASCIIUCADUCETComparison(UChar character)
{
    return isASCII(character) && ducetLevel1Weights[character];
}

template<typename CharacterType1, typename CharacterType2>
UCollationResult compareASCIIWithUCADUCETLevel3(const CharacterType1* characters1, const CharacterType2* characters2, unsigned length)
{
    for (unsigned position = 0; position < length; ++position) {
        auto lhs = characters1[position];
        auto rhs = characters2[position];
        uint8_t leftWeight = ducetLevel3Weights[lhs];
        uint8_t rightWeight = ducetLevel3Weights[rhs];
        if (leftWeight == rightWeight)
            continue;
        return leftWeight > rightWeight ? UCOL_GREATER : UCOL_LESS;
    }
    return UCOL_EQUAL;
}

template<typename CharacterType1, typename CharacterType2>
inline UCollationResult compareASCIIWithUCADUCET(const CharacterType1* characters1, unsigned length1, const CharacterType2* characters2, unsigned length2)
{
    bool notSameCharacters = false;
    unsigned commonLength = std::min(length1, length2);
    for (unsigned position = 0; position < commonLength; ++position) {
        auto lhs = characters1[position];
        auto rhs = characters2[position];
        ASSERT(canUseASCIIUCADUCETComparison(lhs));
        ASSERT(canUseASCIIUCADUCETComparison(rhs));
        if (lhs == rhs)
            continue;
        notSameCharacters = true;
        uint8_t leftWeight = ducetLevel1Weights[lhs];
        uint8_t rightWeight = ducetLevel1Weights[rhs];
        if (leftWeight == rightWeight)
            continue;
        return leftWeight > rightWeight ? UCOL_GREATER : UCOL_LESS;
    }

    if (length1 == length2) {
        if (notSameCharacters)
            return compareASCIIWithUCADUCETLevel3(characters1, characters2, length1);
        return UCOL_EQUAL;
    }
    return length1 > length2 ? UCOL_GREATER : UCOL_LESS;
}

// https://tc39.es/ecma402/#sec-getoptionsobject
inline JSObject* intlGetOptionsObject(JSGlobalObject* globalObject, JSValue options)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    if (options.isUndefined())
        return nullptr;
    if (LIKELY(options.isObject()))
        return asObject(options);
    throwTypeError(globalObject, scope, "options argument is not an object or undefined"_s);
    return nullptr;
}

// https://tc39.es/ecma402/#sec-coerceoptionstoobject
inline JSObject* intlCoerceOptionsToObject(JSGlobalObject* globalObject, JSValue optionsValue)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    if (optionsValue.isUndefined())
        return nullptr;
    JSObject* options = optionsValue.toObject(globalObject);
    RETURN_IF_EXCEPTION(scope, nullptr);
    return options;
}

template<typename Container>
JSArray* createArrayFromStringVector(JSGlobalObject* globalObject, const Container& elements)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), elements.size());
    if (!result) {
        throwOutOfMemoryError(globalObject, scope);
        return nullptr;
    }
    for (unsigned index = 0; index < elements.size(); ++index) {
        result->putDirectIndex(globalObject, index, jsString(vm, elements[index]));
        RETURN_IF_EXCEPTION(scope, { });
    }
    return result;
}

template<typename Container>
JSArray* createArrayFromIntVector(JSGlobalObject* globalObject, const Container& elements)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), elements.size());
    if (!result) {
        throwOutOfMemoryError(globalObject, scope);
        return nullptr;
    }
    for (unsigned index = 0; index < elements.size(); ++index) {
        result->putDirectIndex(globalObject, index, jsNumber(elements[index]));
        RETURN_IF_EXCEPTION(scope, { });
    }
    return result;
}

} // namespace JSC
