#include <LibJS/Runtime/Error.h>
#include <LibJS/Runtime/ValueInlines.h>
#include <LibWeb/Bindings/ExceptionOrUtils.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/SVGClipPathElement.h>
#include <LibWeb/Bindings/SVGElement.h>
#include <LibWeb/SVG/SVGClipPathElement.h>
#include <LibWeb/WebIDL/Tracing.h>

namespace Web::Bindings {

void SVGClipPathElementConstructor::initialize(JS::Realm& realm, JS::NativeFunction& object)
{
    auto& vm = realm.vm();
    [[maybe_unused]] u8 default_attributes = JS::Attribute::Enumerable;

    object.set_prototype(&ensure_web_constructor<SVGElementPrototype>(realm, "SVGElement"_fly_string));
    object.define_direct_property(vm.names.length, JS::Value(0), JS::Attribute::Configurable);
    object.define_direct_property(vm.names.name, JS::PrimitiveString::create(vm, "SVGClipPathElement"_utf16), JS::Attribute::Configurable);
    object.define_direct_property(vm.names.prototype, &ensure_web_prototype<SVGClipPathElementPrototype>(realm, "SVGClipPathElement"_fly_string), 0);
}

JS::ThrowCompletionOr<GC::Ref<JS::Object>> SVGClipPathElementConstructor::construct([[maybe_unused]] InterfaceConstructor& constructor, [[maybe_unused]] JS::FunctionObject& new_target)
{
    WebIDL::log_trace(constructor.vm(), "SVGClipPathElementConstructor::construct");
    return constructor.vm().throw_completion<JS::TypeError>(JS::ErrorType::NotAConstructor, "SVGClipPathElement");
}

void SVGClipPathElementPrototype::initialize(JS::Realm& realm, JS::Object& object)
{
    [[maybe_unused]] auto& vm = realm.vm();
    [[maybe_unused]] u8 default_attributes = JS::Attribute::Enumerable | JS::Attribute::Configurable | JS::Attribute::Writable;

    object.set_prototype(GC::Ref { ensure_web_prototype<SVGElementPrototype>(realm, "SVGElement"_fly_string) });
    object.define_direct_property(vm.well_known_symbol_to_string_tag(), JS::PrimitiveString::create(vm, "SVGClipPathElement"_utf16), JS::Attribute::Configurable);
}

void SVGClipPathElementPrototype::define_unforgeable_attributes(JS::Realm& realm, [[maybe_unused]] JS::Object& object)
{
    [[maybe_unused]] auto& vm = realm.vm();
    [[maybe_unused]] u8 default_attributes = JS::Attribute::Enumerable;
}

[[maybe_unused]] static JS::ThrowCompletionOr<SVG::SVGClipPathElement*> impl_from(JS::VM& vm, JS::Value js_value)
{

    if (auto impl = js_value.as_if<SVG::SVGClipPathElement>())
        return impl.ptr();
    return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SVGClipPathElement");
}

[[maybe_unused]] static JS::ThrowCompletionOr<SVG::SVGClipPathElement*> impl_from(JS::VM& vm)
{
    auto this_value = vm.this_value();
    if (this_value.is_nullish())
        this_value = &vm.current_realm()->global_object();
    return impl_from(vm, this_value);
}

} // namespace Web::Bindings
