#include <LibJS/Runtime/Error.h>
#include <LibJS/Runtime/VM.h>
#include <LibJS/Runtime/ValueInlines.h>
#include <LibWeb/Bindings/Fetching.h>

namespace Web::Bindings {

// https://webidl.spec.whatwg.org/#idl-enumeration
JS::ThrowCompletionOr<CORSSettingsAttribute> convert_to_idl_value_for_cors_settings_attribute(JS::VM& vm, JS::Value value)
{
    // 1. Let S be the result of calling ? ToString(V).
    auto value_as_string = TRY(value.to_utf16_string(vm));

    // 2. If S is not one of E’s enumeration values, then throw a TypeError.
    // 3. Return the enumeration value of type E that is equal to S.
    if (value_as_string == "anonymous"sv)
        return CORSSettingsAttribute::Anonymous;
    if (value_as_string == "use-credentials"sv)
        return CORSSettingsAttribute::UseCredentials;
    return vm.throw_completion<JS::TypeError>(JS::ErrorType::InvalidEnumerationValue, value_as_string, "CORSSettingsAttribute");
}

// https://webidl.spec.whatwg.org/#idl-enumeration
Utf16String idl_enum_to_string(CORSSettingsAttribute value)
{
    // The result of converting an IDL enumeration type value to a JavaScript value is the String value that represents the same sequence of code units as the enumeration value.
    switch (value) {
    case CORSSettingsAttribute::Anonymous:
        return "anonymous"_utf16;
    case CORSSettingsAttribute::UseCredentials:
        return "use-credentials"_utf16;
    }
    VERIFY_NOT_REACHED();
}

// https://webidl.spec.whatwg.org/#idl-enumeration
JS::ThrowCompletionOr<LazyLoadingAttribute> convert_to_idl_value_for_lazy_loading_attribute(JS::VM& vm, JS::Value value)
{
    // 1. Let S be the result of calling ? ToString(V).
    auto value_as_string = TRY(value.to_utf16_string(vm));

    // 2. If S is not one of E’s enumeration values, then throw a TypeError.
    // 3. Return the enumeration value of type E that is equal to S.
    if (value_as_string == "lazy"sv)
        return LazyLoadingAttribute::Lazy;
    if (value_as_string == "eager"sv)
        return LazyLoadingAttribute::Eager;
    return vm.throw_completion<JS::TypeError>(JS::ErrorType::InvalidEnumerationValue, value_as_string, "LazyLoadingAttribute");
}

// https://webidl.spec.whatwg.org/#idl-enumeration
Utf16String idl_enum_to_string(LazyLoadingAttribute value)
{
    // The result of converting an IDL enumeration type value to a JavaScript value is the String value that represents the same sequence of code units as the enumeration value.
    switch (value) {
    case LazyLoadingAttribute::Lazy:
        return "lazy"_utf16;
    case LazyLoadingAttribute::Eager:
        return "eager"_utf16;
    }
    VERIFY_NOT_REACHED();
}

// https://webidl.spec.whatwg.org/#idl-enumeration
JS::ThrowCompletionOr<FetchPriorityAttribute> convert_to_idl_value_for_fetch_priority_attribute(JS::VM& vm, JS::Value value)
{
    // 1. Let S be the result of calling ? ToString(V).
    auto value_as_string = TRY(value.to_utf16_string(vm));

    // 2. If S is not one of E’s enumeration values, then throw a TypeError.
    // 3. Return the enumeration value of type E that is equal to S.
    if (value_as_string == "high"sv)
        return FetchPriorityAttribute::High;
    if (value_as_string == "low"sv)
        return FetchPriorityAttribute::Low;
    if (value_as_string == "auto"sv)
        return FetchPriorityAttribute::Auto;
    return vm.throw_completion<JS::TypeError>(JS::ErrorType::InvalidEnumerationValue, value_as_string, "FetchPriorityAttribute");
}

// https://webidl.spec.whatwg.org/#idl-enumeration
Utf16String idl_enum_to_string(FetchPriorityAttribute value)
{
    // The result of converting an IDL enumeration type value to a JavaScript value is the String value that represents the same sequence of code units as the enumeration value.
    switch (value) {
    case FetchPriorityAttribute::High:
        return "high"_utf16;
    case FetchPriorityAttribute::Low:
        return "low"_utf16;
    case FetchPriorityAttribute::Auto:
        return "auto"_utf16;
    }
    VERIFY_NOT_REACHED();
}

} // namespace Web::Bindings
