//go:build !js && !wasm

package jsrunner

import (
	
	
	
	

	
)

type gojaRunner struct {
	vm *goja.Runtime
}

type gojaValue struct {
	val goja.Value
	vm  *goja.Runtime
}

func () JSRunner {
	return &gojaRunner{vm: goja.New()}
}

// UNUSED
func ( *gojaRunner) ( string) (JSValue, error) {
	return nil, nil
}

func ( *gojaRunner) () Engine {
	return Goja
}

func ( *gojaRunner) ( string) (JSValue, error) {
	,  := .vm.RunString()
	if  != nil {
		return nil, 
	}
	return &gojaValue{val: , vm: .vm}, nil
}

func ( *gojaValue) () string {
	return .val.String()
}

func ( *gojaValue) () interface{} {
	return .val.Export()
}

func ( *gojaRunner) () JSObject {
	return &gojaValue{val: .vm.NewObject(), vm: .vm}
}

func ( *gojaRunner) ( string,  interface{}) error {
	if  == "console" {
		,  := .createConsole()
		if  != nil {
			return 
		}
		return .vm.Set(, )
	}
	return .vm.Set(, )
}

func ( *gojaRunner) ( context.Context,  JSValue) (interface{}, error) {
	 := .(*gojaValue)
	 := .val.Export()
	 := .(*goja.Promise)

	for .State() == goja.PromiseStatePending {
		if  := .Err();  != nil {
			return nil, 
		}
		continue
	}

	if .State() == goja.PromiseStateRejected {
		return nil, errors.New("Promise rejected")
	}

	return .Result().Export(), nil
}

func ( *gojaRunner) () (*goja.Object, error) {
	 := .vm
	 := .NewObject()

	if  := .Set("log", .ToValue(func( goja.FunctionCall) goja.Value {
		 := make([]interface{}, len(.Arguments))
		for ,  := range .Arguments {
			[] = .Export()
		}
		fmt.Println(...)
		return nil
	}));  != nil {
		return nil, 
	}

	if  := .Set("error", .ToValue(func( goja.FunctionCall) goja.Value {
		 := make([]interface{}, len(.Arguments))
		for ,  := range .Arguments {
			[] = .Export()
		}
		fmt.Fprintln(os.Stderr, ...)
		return nil
	}));  != nil {
		return nil, 
	}

	return , nil
}