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

namespace Web::Bindings {

// https://webidl.spec.whatwg.org/#idl-enumeration
JS::ThrowCompletionOr<CanvasFontKerning> convert_to_idl_value_for_canvas_font_kerning(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 == "auto"sv)
        return CanvasFontKerning::Auto;
    if (value_as_string == "normal"sv)
        return CanvasFontKerning::Normal;
    if (value_as_string == "none"sv)
        return CanvasFontKerning::None;
    return vm.throw_completion<JS::TypeError>(JS::ErrorType::InvalidEnumerationValue, value_as_string, "CanvasFontKerning");
}

// https://webidl.spec.whatwg.org/#idl-enumeration
Utf16String idl_enum_to_string(CanvasFontKerning 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 CanvasFontKerning::Auto:
        return "auto"_utf16;
    case CanvasFontKerning::Normal:
        return "normal"_utf16;
    case CanvasFontKerning::None:
        return "none"_utf16;
    }
    VERIFY_NOT_REACHED();
}

// https://webidl.spec.whatwg.org/#idl-enumeration
JS::ThrowCompletionOr<CanvasFontStretch> convert_to_idl_value_for_canvas_font_stretch(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 == "ultra-condensed"sv)
        return CanvasFontStretch::UltraCondensed;
    if (value_as_string == "extra-condensed"sv)
        return CanvasFontStretch::ExtraCondensed;
    if (value_as_string == "condensed"sv)
        return CanvasFontStretch::Condensed;
    if (value_as_string == "semi-condensed"sv)
        return CanvasFontStretch::SemiCondensed;
    if (value_as_string == "normal"sv)
        return CanvasFontStretch::Normal;
    if (value_as_string == "semi-expanded"sv)
        return CanvasFontStretch::SemiExpanded;
    if (value_as_string == "expanded"sv)
        return CanvasFontStretch::Expanded;
    if (value_as_string == "extra-expanded"sv)
        return CanvasFontStretch::ExtraExpanded;
    if (value_as_string == "ultra-expanded"sv)
        return CanvasFontStretch::UltraExpanded;
    return vm.throw_completion<JS::TypeError>(JS::ErrorType::InvalidEnumerationValue, value_as_string, "CanvasFontStretch");
}

// https://webidl.spec.whatwg.org/#idl-enumeration
Utf16String idl_enum_to_string(CanvasFontStretch 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 CanvasFontStretch::UltraCondensed:
        return "ultra-condensed"_utf16;
    case CanvasFontStretch::ExtraCondensed:
        return "extra-condensed"_utf16;
    case CanvasFontStretch::Condensed:
        return "condensed"_utf16;
    case CanvasFontStretch::SemiCondensed:
        return "semi-condensed"_utf16;
    case CanvasFontStretch::Normal:
        return "normal"_utf16;
    case CanvasFontStretch::SemiExpanded:
        return "semi-expanded"_utf16;
    case CanvasFontStretch::Expanded:
        return "expanded"_utf16;
    case CanvasFontStretch::ExtraExpanded:
        return "extra-expanded"_utf16;
    case CanvasFontStretch::UltraExpanded:
        return "ultra-expanded"_utf16;
    }
    VERIFY_NOT_REACHED();
}

// https://webidl.spec.whatwg.org/#idl-enumeration
JS::ThrowCompletionOr<CanvasFontVariantCaps> convert_to_idl_value_for_canvas_font_variant_caps(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 == "normal"sv)
        return CanvasFontVariantCaps::Normal;
    if (value_as_string == "small-caps"sv)
        return CanvasFontVariantCaps::SmallCaps;
    if (value_as_string == "all-small-caps"sv)
        return CanvasFontVariantCaps::AllSmallCaps;
    if (value_as_string == "petite-caps"sv)
        return CanvasFontVariantCaps::PetiteCaps;
    if (value_as_string == "all-petite-caps"sv)
        return CanvasFontVariantCaps::AllPetiteCaps;
    if (value_as_string == "unicase"sv)
        return CanvasFontVariantCaps::Unicase;
    if (value_as_string == "titling-caps"sv)
        return CanvasFontVariantCaps::TitlingCaps;
    return vm.throw_completion<JS::TypeError>(JS::ErrorType::InvalidEnumerationValue, value_as_string, "CanvasFontVariantCaps");
}

// https://webidl.spec.whatwg.org/#idl-enumeration
Utf16String idl_enum_to_string(CanvasFontVariantCaps 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 CanvasFontVariantCaps::Normal:
        return "normal"_utf16;
    case CanvasFontVariantCaps::SmallCaps:
        return "small-caps"_utf16;
    case CanvasFontVariantCaps::AllSmallCaps:
        return "all-small-caps"_utf16;
    case CanvasFontVariantCaps::PetiteCaps:
        return "petite-caps"_utf16;
    case CanvasFontVariantCaps::AllPetiteCaps:
        return "all-petite-caps"_utf16;
    case CanvasFontVariantCaps::Unicase:
        return "unicase"_utf16;
    case CanvasFontVariantCaps::TitlingCaps:
        return "titling-caps"_utf16;
    }
    VERIFY_NOT_REACHED();
}

// https://webidl.spec.whatwg.org/#idl-enumeration
JS::ThrowCompletionOr<CanvasTextRendering> convert_to_idl_value_for_canvas_text_rendering(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 == "auto"sv)
        return CanvasTextRendering::Auto;
    if (value_as_string == "optimizeSpeed"sv)
        return CanvasTextRendering::Optimizespeed;
    if (value_as_string == "optimizeLegibility"sv)
        return CanvasTextRendering::Optimizelegibility;
    if (value_as_string == "geometricPrecision"sv)
        return CanvasTextRendering::Geometricprecision;
    return vm.throw_completion<JS::TypeError>(JS::ErrorType::InvalidEnumerationValue, value_as_string, "CanvasTextRendering");
}

// https://webidl.spec.whatwg.org/#idl-enumeration
Utf16String idl_enum_to_string(CanvasTextRendering 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 CanvasTextRendering::Auto:
        return "auto"_utf16;
    case CanvasTextRendering::Optimizespeed:
        return "optimizeSpeed"_utf16;
    case CanvasTextRendering::Optimizelegibility:
        return "optimizeLegibility"_utf16;
    case CanvasTextRendering::Geometricprecision:
        return "geometricPrecision"_utf16;
    }
    VERIFY_NOT_REACHED();
}

} // namespace Web::Bindings
