#pragma once

#include <AK/Optional.h>
#include <LibJS/Forward.h>
#include <LibJS/Runtime/NativeFunction.h>
#include <LibJS/Runtime/Object.h>
#include <LibJS/Runtime/Value.h>
#include <LibWeb/Bindings/IDBCursor.h>
#include <LibWeb/Bindings/InterfaceObject.h>
#include <LibWeb/WebIDL/Types.h>

namespace Web::Bindings {

struct IDBObjectStoreConstructor {
public:
    static void initialize(JS::Realm&, JS::NativeFunction&);
    static JS::ThrowCompletionOr<GC::Ref<JS::Object>> construct(InterfaceConstructor&, JS::FunctionObject&);

private:
};

struct IDBObjectStorePrototype {
public:
    static void initialize(JS::Realm&, JS::Object&);
    static void define_unforgeable_attributes(JS::Realm&, JS::Object&);

private:
    JS_DECLARE_NATIVE_FUNCTION(name_getter);
    JS_DECLARE_NATIVE_FUNCTION(name_setter);
    JS_DECLARE_NATIVE_FUNCTION(key_path_getter);
    JS_DECLARE_NATIVE_FUNCTION(index_names_getter);
    JS_DECLARE_NATIVE_FUNCTION(transaction_getter);
    JS_DECLARE_NATIVE_FUNCTION(auto_increment_getter);
    JS_DECLARE_NATIVE_FUNCTION(put);
    JS_DECLARE_NATIVE_FUNCTION(add);
    JS_DECLARE_NATIVE_FUNCTION(delete_);
    JS_DECLARE_NATIVE_FUNCTION(clear);
    JS_DECLARE_NATIVE_FUNCTION(get);
    JS_DECLARE_NATIVE_FUNCTION(get_key);
    JS_DECLARE_NATIVE_FUNCTION(get_all);
    JS_DECLARE_NATIVE_FUNCTION(get_all_keys);
    JS_DECLARE_NATIVE_FUNCTION(get_all_records);
    JS_DECLARE_NATIVE_FUNCTION(count);
    JS_DECLARE_NATIVE_FUNCTION(open_cursor);
    JS_DECLARE_NATIVE_FUNCTION(open_key_cursor);
    JS_DECLARE_NATIVE_FUNCTION(index);
    JS_DECLARE_NATIVE_FUNCTION(create_index);
    JS_DECLARE_NATIVE_FUNCTION(delete_index);
};

struct IDBIndexParameters {
    bool multi_entry { false };
    bool unique { false };
};

JS::ThrowCompletionOr<IDBIndexParameters> convert_to_idl_value_for_idb_index_parameters(JS::VM&, JS::Value);

struct IDBGetAllOptions {
    Optional<WebIDL::UnsignedLong> count {};
    IDBCursorDirection direction { IDBCursorDirection::Next };
    JS::Value query { JS::js_null() };
};

JS::ThrowCompletionOr<IDBGetAllOptions> convert_to_idl_value_for_idb_get_all_options(JS::VM&, JS::Value);

} // namespace Web::Bindings
