package goja

import (
	
)

type nativeProxyHandler struct {
	handler *ProxyTrapConfig
}

func ( *nativeProxyHandler) ( *Object) (Value, bool) {
	if  := .handler.GetPrototypeOf;  != nil {
		return (), true
	}
	return nil, false
}

func ( *nativeProxyHandler) ( *Object,  *Object) (bool, bool) {
	if  := .handler.SetPrototypeOf;  != nil {
		return (, ), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object) (bool, bool) {
	if  := .handler.IsExtensible;  != nil {
		return (), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object) (bool, bool) {
	if  := .handler.PreventExtensions;  != nil {
		return (), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object,  unistring.String) (Value, bool) {
	if  := .handler.GetOwnPropertyDescriptorIdx;  != nil {
		if ,  := strToInt();  {
			 := (, )
			return .toValue(.runtime), true
		}
	}
	if  := .handler.GetOwnPropertyDescriptor;  != nil {
		 := (, .String())
		return .toValue(.runtime), true
	}
	return nil, false
}

func ( *nativeProxyHandler) ( *Object,  valueInt) (Value, bool) {
	if  := .handler.GetOwnPropertyDescriptorIdx;  != nil {
		 := (, toIntStrict(int64()))
		return .toValue(.runtime), true
	}
	if  := .handler.GetOwnPropertyDescriptor;  != nil {
		 := (, .String())
		return .toValue(.runtime), true
	}
	return nil, false
}

func ( *nativeProxyHandler) ( *Object,  *Symbol) (Value, bool) {
	if  := .handler.GetOwnPropertyDescriptorSym;  != nil {
		 := (, )
		return .toValue(.runtime), true
	}
	return nil, false
}

func ( *nativeProxyHandler) ( *Object,  unistring.String,  PropertyDescriptor) (bool, bool) {
	if  := .handler.DefinePropertyIdx;  != nil {
		if ,  := strToInt();  {
			return (, , ), true
		}
	}
	if  := .handler.DefineProperty;  != nil {
		return (, .String(), ), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object,  valueInt,  PropertyDescriptor) (bool, bool) {
	if  := .handler.DefinePropertyIdx;  != nil {
		return (, toIntStrict(int64()), ), true
	}
	if  := .handler.DefineProperty;  != nil {
		return (, .String(), ), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object,  *Symbol,  PropertyDescriptor) (bool, bool) {
	if  := .handler.DefinePropertySym;  != nil {
		return (, , ), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object,  unistring.String) (bool, bool) {
	if  := .handler.HasIdx;  != nil {
		if ,  := strToInt();  {
			return (, ), true
		}
	}
	if  := .handler.Has;  != nil {
		return (, .String()), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object,  valueInt) (bool, bool) {
	if  := .handler.HasIdx;  != nil {
		return (, toIntStrict(int64())), true
	}
	if  := .handler.Has;  != nil {
		return (, .String()), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object,  *Symbol) (bool, bool) {
	if  := .handler.HasSym;  != nil {
		return (, ), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object,  unistring.String,  Value) (Value, bool) {
	if  := .handler.GetIdx;  != nil {
		if ,  := strToInt();  {
			return (, , ), true
		}
	}
	if  := .handler.Get;  != nil {
		return (, .String(), ), true
	}
	return nil, false
}

func ( *nativeProxyHandler) ( *Object,  valueInt,  Value) (Value, bool) {
	if  := .handler.GetIdx;  != nil {
		return (, toIntStrict(int64()), ), true
	}
	if  := .handler.Get;  != nil {
		return (, .String(), ), true
	}
	return nil, false
}

func ( *nativeProxyHandler) ( *Object,  *Symbol,  Value) (Value, bool) {
	if  := .handler.GetSym;  != nil {
		return (, , ), true
	}
	return nil, false
}

func ( *nativeProxyHandler) ( *Object,  unistring.String,  Value,  Value) (bool, bool) {
	if  := .handler.SetIdx;  != nil {
		if ,  := strToInt();  {
			return (, , , ), true
		}
	}
	if  := .handler.Set;  != nil {
		return (, .String(), , ), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object,  valueInt,  Value,  Value) (bool, bool) {
	if  := .handler.SetIdx;  != nil {
		return (, toIntStrict(int64()), , ), true
	}
	if  := .handler.Set;  != nil {
		return (, .String(), , ), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object,  *Symbol,  Value,  Value) (bool, bool) {
	if  := .handler.SetSym;  != nil {
		return (, , , ), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object,  unistring.String) (bool, bool) {
	if  := .handler.DeletePropertyIdx;  != nil {
		if ,  := strToInt();  {
			return (, ), true
		}
	}
	if  := .handler.DeleteProperty;  != nil {
		return (, .String()), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object,  valueInt) (bool, bool) {
	if  := .handler.DeletePropertyIdx;  != nil {
		return (, toIntStrict(int64())), true
	}
	if  := .handler.DeleteProperty;  != nil {
		return (, .String()), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object,  *Symbol) (bool, bool) {
	if  := .handler.DeletePropertySym;  != nil {
		return (, ), true
	}
	return false, false
}

func ( *nativeProxyHandler) ( *Object) (*Object, bool) {
	if  := .handler.OwnKeys;  != nil {
		return (), true
	}
	return nil, false
}

func ( *nativeProxyHandler) ( *Object,  Value,  []Value) (Value, bool) {
	if  := .handler.Apply;  != nil {
		return (, , ), true
	}
	return nil, false
}

func ( *nativeProxyHandler) ( *Object,  []Value,  *Object) (Value, bool) {
	if  := .handler.Construct;  != nil {
		return (, , ), true
	}
	return nil, false
}

func ( *nativeProxyHandler) ( *Runtime) *Object {
	return .ToValue(.handler).ToObject()
}

func ( *Runtime) ( *ProxyTrapConfig) proxyHandler {
	return &nativeProxyHandler{handler: }
}

// ProxyTrapConfig provides a simplified Go-friendly API for implementing Proxy traps.
// If an *Idx trap is defined it gets called for integer property keys, including negative ones. Note that
// this only includes string property keys that represent a canonical integer
// (i.e. "0", "123", but not "00", "01", " 1" or "-0").
// For efficiency strings representing integers exceeding 2^53 are not checked to see if they are canonical,
// i.e. the *Idx traps will receive "9007199254740993" as well as "9007199254740994", even though the former is not
// a canonical representation in ECMAScript (Number("9007199254740993") === 9007199254740992).
// See https://262.ecma-international.org/#sec-canonicalnumericindexstring
// If an *Idx trap is not set, the corresponding string one is used.
type ProxyTrapConfig struct {
	// A trap for Object.getPrototypeOf, Reflect.getPrototypeOf, __proto__, Object.prototype.isPrototypeOf, instanceof
	GetPrototypeOf func(target *Object) (prototype *Object)

	// A trap for Object.setPrototypeOf, Reflect.setPrototypeOf
	SetPrototypeOf func(target *Object, prototype *Object) (success bool)

	// A trap for Object.isExtensible, Reflect.isExtensible
	IsExtensible func(target *Object) (success bool)

	// A trap for Object.preventExtensions, Reflect.preventExtensions
	PreventExtensions func(target *Object) (success bool)

	// A trap for Object.getOwnPropertyDescriptor, Reflect.getOwnPropertyDescriptor (string properties)
	GetOwnPropertyDescriptor func(target *Object, prop string) (propertyDescriptor PropertyDescriptor)

	// A trap for Object.getOwnPropertyDescriptor, Reflect.getOwnPropertyDescriptor (integer properties)
	GetOwnPropertyDescriptorIdx func(target *Object, prop int) (propertyDescriptor PropertyDescriptor)

	// A trap for Object.getOwnPropertyDescriptor, Reflect.getOwnPropertyDescriptor (Symbol properties)
	GetOwnPropertyDescriptorSym func(target *Object, prop *Symbol) (propertyDescriptor PropertyDescriptor)

	// A trap for Object.defineProperty, Reflect.defineProperty (string properties)
	DefineProperty func(target *Object, key string, propertyDescriptor PropertyDescriptor) (success bool)

	// A trap for Object.defineProperty, Reflect.defineProperty (integer properties)
	DefinePropertyIdx func(target *Object, key int, propertyDescriptor PropertyDescriptor) (success bool)

	// A trap for Object.defineProperty, Reflect.defineProperty (Symbol properties)
	DefinePropertySym func(target *Object, key *Symbol, propertyDescriptor PropertyDescriptor) (success bool)

	// A trap for the in operator, with operator, Reflect.has (string properties)
	Has func(target *Object, property string) (available bool)

	// A trap for the in operator, with operator, Reflect.has (integer properties)
	HasIdx func(target *Object, property int) (available bool)

	// A trap for the in operator, with operator, Reflect.has (Symbol properties)
	HasSym func(target *Object, property *Symbol) (available bool)

	// A trap for getting property values, Reflect.get (string properties)
	Get func(target *Object, property string, receiver Value) (value Value)

	// A trap for getting property values, Reflect.get (integer properties)
	GetIdx func(target *Object, property int, receiver Value) (value Value)

	// A trap for getting property values, Reflect.get (Symbol properties)
	GetSym func(target *Object, property *Symbol, receiver Value) (value Value)

	// A trap for setting property values, Reflect.set (string properties)
	Set func(target *Object, property string, value Value, receiver Value) (success bool)

	// A trap for setting property values, Reflect.set (integer properties)
	SetIdx func(target *Object, property int, value Value, receiver Value) (success bool)

	// A trap for setting property values, Reflect.set (Symbol properties)
	SetSym func(target *Object, property *Symbol, value Value, receiver Value) (success bool)

	// A trap for the delete operator, Reflect.deleteProperty (string properties)
	DeleteProperty func(target *Object, property string) (success bool)

	// A trap for the delete operator, Reflect.deleteProperty (integer properties)
	DeletePropertyIdx func(target *Object, property int) (success bool)

	// A trap for the delete operator, Reflect.deleteProperty (Symbol properties)
	DeletePropertySym func(target *Object, property *Symbol) (success bool)

	// A trap for Object.getOwnPropertyNames, Object.getOwnPropertySymbols, Object.keys, Reflect.ownKeys
	OwnKeys func(target *Object) (object *Object)

	// A trap for a function call, Function.prototype.apply, Function.prototype.call, Reflect.apply
	Apply func(target *Object, this Value, argumentsList []Value) (value Value)

	// A trap for the new operator, Reflect.construct
	Construct func(target *Object, argumentsList []Value, newTarget *Object) (value *Object)
}

func ( *Runtime) ( []Value,  *Object) *Object {
	if len() >= 2 {
		if ,  := [0].(*Object);  {
			if ,  := [1].(*Object);  {
				return .newProxyObject(, , ).val
			}
		}
	}
	panic(.NewTypeError("Cannot create proxy with a non-object as target or handler"))
}

func ( *Runtime) ( []Value,  *Object) *Object {
	if  == nil {
		panic(.needNew("Proxy"))
	}
	return .newProxy(, .getPrototypeFromCtor(, .getProxy(), .global.ObjectPrototype))
}

func ( *Runtime) ( *Object,  *ProxyTrapConfig) Proxy {
	if ,  := .self.(*proxyObject);  {
		if .handler == nil {
			panic(.NewTypeError("Cannot create proxy with a revoked proxy as target"))
		}
	}
	 := .newNativeProxyHandler()
	 := ._newProxyObject(, , nil)
	return Proxy{proxy: }
}

func ( *Runtime) ( FunctionCall) Value {
	if len(.Arguments) >= 2 {
		if ,  := .Argument(0).(*Object);  {
			if ,  := .Argument(1).(*Object);  {
				 := .newProxyObject(, , nil)
				 := .newNativeFunc(func(FunctionCall) Value {
					.revoke()
					return _undefined
				}, "", 0)
				 := .NewObject()
				.self._putProp("proxy", .val, true, true, true)
				.self._putProp("revoke", , true, true, true)
				return 
			}
		}
	}
	panic(.NewTypeError("Cannot create proxy with a non-object as target or handler"))
}

func ( *Runtime) ( *Object) objectImpl {
	 := .newNativeConstructOnly(, .builtin_newProxy, nil, "Proxy", 2)

	._putProp("revocable", .newNativeFunc(.builtin_proxy_revocable, "revocable", 2), true, false, true)
	return 
}

func ( *Runtime) () *Object {
	 := .global.Proxy
	if  == nil {
		 = &Object{runtime: }
		.global.Proxy = 
		.createProxy()
	}
	return 
}