{{/*
 Copyright 2021 The Dawn & Tint Authors

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:

 1. Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

 3. Neither the name of the copyright holder nor the names of its
    contributors may be used to endorse or promote products derived from
    this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/}}

{{- /*
--------------------------------------------------------------------------------
Template file for use with tools/src/cmd/idlgen/main.go to generate the
WebGPU.cpp source file.

See:
* https://github.com/ben-clayton/webidlparser/blob/main/ast/ast.go for the AST
  types used by this template
* tools/src/cmd/idlgen/main.go for additional structures and functions
  used by this template
* https://golang.org/pkg/text/template/ for documentation on the template syntax
--------------------------------------------------------------------------------
*/ -}}

{{- Include "WebGPUCommon.tmpl" -}}

#include "src/dawn/node/interop/WebGPU.h"

#include <unordered_map>

#include "src/dawn/node/utils/Debug.h"
#include "src/dawn/node/binding/Errors.h"

namespace wgpu {
namespace interop {

namespace {

// This is passed to constructors so that constructor can
// check if it's being called legitimately from C++ or
// illegitimately from JavaScript.
static void* kInternalConstructionMarker = nullptr;

{{template "Wrappers" $}}

}  // namespace

const Constructors* ConstructorsFor(Napi::Env env) {
  return Wrappers::For(env);
}

{{ range $ := .Declarations}}
{{-        if IsDictionary $}}{{template "Dictionary" $}}
{{-   else if IsInterface  $}}{{template "Interface"  $}}
{{-   else if IsEnum       $}}{{template "Enum"       $}}
{{-   end}}
{{- end}}


Napi::Object Initialize(Napi::Env env) {
  auto* wrapper = Wrappers::Init(env);
  auto exports = Napi::Object::New(env);
{{- range $ := .Declarations}}
{{-   if IsInterfaceOrNamespace $}}
{{-     if not (HasAnnotation $ "LegacyNoInterfaceObject")}}
  exports.Set(Napi::String::New(env, "{{$.Name}}"), wrapper->{{$.Name}}_ctor.Value());
{{-     end}}
{{-   end}}
{{- end}}
  return exports;
}

}  // namespace interop
}  // namespace wgpu


{{- /*
--------------------------------------------------------------------------------
-- Wrappers emits the C++ 'Wrappers' class, which holds all the interface and
-- namespace interop wrapper classes.
--------------------------------------------------------------------------------
*/ -}}
{{- define "Wrappers"}}
// Wrappers holds all the Napi class constructors, and Napi::ObjectWrap type
// declarations, for each of the WebIDL interface and namespace types.
class Wrappers : public Constructors  {
  Wrappers(Napi::Env env) : Constructors(env) {
{{-   range $ := .Declarations}}
{{-     if and (IsInterfaceOrNamespace $) (not (HasAnnotation $ "ManualImplementation"))}}
{{-       if and (IsInterface $) ($.Inherits)}}
    {
      // It's an interface and it inherits from another class, pass the class it inherits
      // from to its Class factory
      Napi::Value baseClassValue = {{$.Inherits}}_ctor.Value();
      {{$.Name}}_ctor = Napi::Persistent(W{{$.Name}}::Class(env, baseClassValue));
    }
{{-       else}}
    {{$.Name}}_ctor = Napi::Persistent(W{{$.Name}}::Class(env));
{{-       end}}
{{-     end}}
{{-   end}}
  }

public:
{{-   range $ := .Declarations}}
{{-     if and (IsInterfaceOrNamespace $) (not (HasAnnotation $ "ManualImplementation"))}}
  {{template "Wrapper" $}}
{{-     end}}
{{-   end}}

  static void Delete(Napi::Env, Wrappers* data) {
    delete data;
  }

  // Allocates and constructs the Wrappers instance
  static Wrappers* Init(Napi::Env env) {
    auto instance = new Wrappers(env);
    env.SetInstanceData<Wrappers, &Wrappers::Delete>(instance);
    return instance;
  }

  // Destructs and frees the Wrappers instance
  static void Term(Napi::Env env) {
    env.SetInstanceData<Wrappers>(nullptr);
  }

  static Constructors* For(Napi::Env env) {
    return env.GetInstanceData<Wrappers>();
  }
};
{{- end}}


{{- /*
--------------------------------------------------------------------------------
-- Wrapper emits the C++ wrapper class for the given ast.Interface or
-- ast.Namespace.
-- This wrapper class inherits from Napi::ObjectWrap, which binds the lifetime
-- of the JavaScript object to the lifetime of the wrapper class instance.
-- If the wrapper is for an interface, the wrapper object holds a unique_ptr to
-- the interface implementation, and delegates all exposed method calls on to
-- the implementation.
-- See: https://github.com/nodejs/node-addon-api/blob/main/doc/object_wrap.md
--------------------------------------------------------------------------------
*/ -}}
{{- define "Wrapper"}}
  struct W{{$.Name}} : public Napi::ObjectWrap<W{{$.Name}}> {
{{-  $attributes := FlattenedAttributesOf $ }}
{{-  $constants  := FlattenedConstantsOf  $ }}
{{-  $methods    := FlattenedMethodsOf    $ }}
{{-  if IsInterface $}}
    std::unique_ptr<{{$.Name}}> impl;
{{-  end}}
{{-  if and (IsInterface $) ($.Inherits) }}
    // This class inherits from another, require the class factory to
    // receive the base class so it can setup inheritance.
    static Napi::Function Class(Napi::Env env, Napi::Value baseClassValue) {
{{-  else}}
    static Napi::Function Class(Napi::Env env) {
{{-  end}}
      auto func = DefineClass(env, "{{$.Name}}", {
{{   if $s := SetlikeOf $}}
        InstanceMethod("has", &W{{$.Name}}::has),
        InstanceMethod("keys", &W{{$.Name}}::keys),
        InstanceAccessor("size", &W{{$.Name}}::getSize, nullptr),
        InstanceMethod(Napi::Symbol::WellKnown(env,"iterator"), &W{{$.Name}}::iterator),
{{-  end}}
{{-  range $m := $methods}}
        InstanceMethod("{{$m.Name}}", &W{{$.Name}}::{{$m.Name}}, static_cast<napi_property_attributes>(napi_default_jsproperty)),
{{-  end}}
{{-  range $a := $attributes}}
{{-   if not (HasAnnotation $a "SameObject")}}
        InstanceAccessor("{{$a.Name}}", &W{{$.Name}}::get{{Title $a.Name}},
{{-    if $a.Readonly}} nullptr,{{else}} &W{{$.Name}}::set{{Title $a.Name}},{{end -}}
        napi_default_jsproperty),
{{-   end}}
{{-  end}}
{{-  range $c := $constants}}
        StaticValue("{{$c.Name}}", ToJS(env, {{$.Name}}::{{$c.Name}}), napi_default_jsproperty),
{{-  end}}
      });

{{-  if and (IsInterface $) ($.Inherits)}}
      // It inherits from another class, setup the prototype chain.
      ChainPrototype(baseClassValue, func);
{{-  end}}
      return func;
    }

    W{{$.Name}}(const Napi::CallbackInfo& info) : ObjectWrap(info) {
{{-   if IsInterface $}}
{{-     if HasConstructor $}}

{{-  range $m := $.Members}}
{{-    if IsInitializer $m}}
      {
        {{template "ParameterTupleDecl" $m}}
        auto res = FromJS(info, args);
        if (res) {
          impl = std::make_unique<wgpu::binding::{{$.Name}}>(args);
        }
      }
      // No constructor matched.
      if (impl == nullptr) {
        Napi::TypeError::New(info.Env(), "No constructor matched.").ThrowAsJavaScriptException();
      }
{{-      end}}
{{-  end}}


{{-     else}}
        // Check if the first argument is our internal Napi::External<void> marker
        // to prevent JavaScript from constructing this non-constructable object.
        if (info.Length() < 1 || !info[0].IsExternal() || info[0].As<Napi::External<void>>().Data() != &kInternalConstructionMarker) {
           Napi::TypeError::New(info.Env(), "Failed to construct '{{$.Name}}': Illegal constructor").ThrowAsJavaScriptException();
         }
{{-     end}}
{{-   end}}
    }

{{-  if $s := SetlikeOf $}}
    Napi::Value has(const Napi::CallbackInfo& info) {
      std::tuple<{{template "Type" $s.Elem}}> args;
      auto res = FromJS(info, args);
      if (res) {
          return ToJS(info.Env(), impl->has(info.Env(), std::get<0>(args)));
      }
      Napi::TypeError::New(info.Env(), res.error).ThrowAsJavaScriptException();
      return {};
    }
    Napi::Value keys(const Napi::CallbackInfo& info) {
      return ToJS(info.Env(), impl->keys(info.Env()));
    }
    Napi::Value getSize(const Napi::CallbackInfo& info) {
      return ToJS(info.Env(), impl->getSize(info.Env()));
    }
    Napi::Value iterator(const Napi::CallbackInfo& info) {
      return impl->iterator(info);
    }
{{-  end}}
{{-  range $m := $methods}}
{{-    $implSuffix := ""}}
{{-    if ReturnsPromise $m}}
{{-      $implSuffix = "Inner"}}
    Napi::Value {{$m.Name}}(const Napi::CallbackInfo& info) {
      return CatchExceptionIntoPromise(info.Env(), [&]() -> auto { return {{$m.Name}}Inner(info); });
    }
{{-    end}}
    Napi::Value {{$m.Name}}{{$implSuffix}}(const Napi::CallbackInfo& info) {
      std::string error;
{{-    range $overload_idx, $o := $m.Overloads}}
{{- $overloaded := gt (len $m.Overloads) 1}}
      { {{if $overloaded}}// Overload {{$overload_idx}}{{end}}
        {{template "ParameterTupleDecl" $o}}
        auto res = FromJS(info, args);
        if (res) {
          {{/* indent */}}INTEROP_LOG(
{{-        range $i, $p := $o.Parameters}}
{{-          if $i}}, ", {{$p.Name}}: "{{else}}"{{$p.Name}}: "{{end}}, std::get<{{$i}}>(args)
{{-        end}});
          {{/* indent */}}
{{-      if not (IsUndefinedType $o.Type) }}auto result = {{end -}}
          impl->{{$o.Name}}(info.Env(){{range $i, $_ := $o.Parameters}}, std::get<{{$i}}>(args){{end}});
          {{/* indent */ -}}
{{-      if   IsUndefinedType $o.Type}}return info.Env().Undefined();
{{-      else                        }}return ToJS(info.Env(), result);
{{-      end                         }}
        }
        error = {{if $overloaded}}"\noverload {{$overload_idx}} failed to match:\n" + {{end}}res.error;
      }
{{-    end}}
      Napi::TypeError::New(info.Env(), "no overload matched for {{$m.Name}}:\n" + error).ThrowAsJavaScriptException();
      return {};
    }
{{-  end}}

{{-  range $a := $attributes}}
{{-   if not (HasAnnotation $a "SameObject")}}
    Napi::Value get{{Title $a.Name}}(const Napi::CallbackInfo& info) {
      return ToJS(info.Env(), impl->get{{Title $a.Name}}(info.Env()));
    }
{{-   if not $a.Readonly}}
    void set{{Title $a.Name}}(const Napi::CallbackInfo& info, const Napi::Value& value) {
      {{template "Type" $a.Type}} v{};
      auto res = FromJS(info.Env(), value, v);
      if (res) {
        impl->set{{Title $a.Name}}(info.Env(), std::move(v));
      } else {
        res = res.Append("invalid value to {{$a.Name}}");
        Napi::TypeError::New(info.Env(), res.error).ThrowAsJavaScriptException();
      }
    }
{{-    end}}
{{-   end}}
{{-  end}}
  };
{{end}}

{{- /*
--------------------------------------------------------------------------------
-- Emits a tuple "args" for function argument conversion from JS to C++
--------------------------------------------------------------------------------

*/ -}}
{{- define "ParameterTupleDecl"}}
        std::tuple<
{{-        range $i, $p := $.Parameters}}
{{-          if $i}}, {{end}}
{{-          if      $p.Init    }}DefaultedParameter<{{template "Type" $p.Type}}>
{{-          else if $p.Optional}}std::optional<{{template "Type" $p.Type}}>
{{-          else               }}{{template "Type" $p.Type}}
{{-          end}}
{{-        end}}> args;

{{-        range $i, $p := $.Parameters}}
{{-          if $p.Init}}
        std::get<{{$i}} /* {{$p.Name}} */>(args).default_value = {{Eval "Literal" "Value" $p.Init "Type" $p.Type}};
{{-          end}}
{{-        end}}

{{- end}}

{{- /*
--------------------------------------------------------------------------------
-- Dictionary emits the C++ method implementations and associated functions of
-- the interop type that defines the given ast.Dictionary
--------------------------------------------------------------------------------
*/ -}}
{{- define "Dictionary"}}
Result Converter<{{$.Name}}>::FromJS(Napi::Env env, Napi::Value value, {{$.Name}}& out) {
  auto object = value.ToObject();
  Result res;
{{- template "DictionaryMembersFromJS" $}}
  return Success;
}

Napi::Value Converter<{{$.Name}}>::ToJS(Napi::Env env, {{$.Name}} value) {
  auto object = Napi::Object::New(env);
{{- template "DictionaryMembersToJS" $}}
  return object;
}

std::ostream& operator<<(std::ostream& o, const {{$.Name}}& dict) {
    o << "{{$.Name}} {";
{{-    range $i, $m := $.Members}}
    o << {{if $i}}", "{{else}}" "{{end}} << "{{$m.Name}}: ";
    utils::Write(o, dict.{{$m.Name}});
{{-    end          }}
    o << "}\n";
    return o;
}
{{ end}}


{{- /*
--------------------------------------------------------------------------------
-- DictionaryMembersFromJS emits the C++ logic to convert each of the
-- dictionary ast.Member fields from JavaScript to C++. Each call to ToJS() is
-- emitted as a separate statement, and requires a 'Result res' local to be
-- declared
--------------------------------------------------------------------------------
*/ -}}
{{- define "DictionaryMembersFromJS"}}
{{-    if $.Inherits}}{{template "DictionaryMembersFromJS" (Lookup $.Inherits)}}{{end}}
{{-    range $i, $m := $.Members}}
  {{/* indent */}}
{{-      if   $m.Init }}res = interop::FromJSOptional(env, object.Get("{{$m.Name}}"), out.{{$m.Name}});
{{-      else         }}res = interop::FromJS(env, object.Get("{{$m.Name}}"), out.{{$m.Name}});
{{-      end          }}
  if (!res) {
    return res.Append("while converting member '{{$m.Name}}'");
  }
{{-    else}}
  (void)object;
{{-    end}}
{{- end}}


{{- /*
--------------------------------------------------------------------------------
-- DictionaryMembersToJS emits the C++ logic to convert each of the
-- dictionary ast.Member fields to JavaScript from C++. Each call to ToJS() is
-- emitted as a separate statement
--------------------------------------------------------------------------------
*/ -}}
{{- define "DictionaryMembersToJS"}}
{{-    if $.Inherits}}{{template "DictionaryMembersToJS" (Lookup $.Inherits)}}{{end}}
{{-    range $m := $.Members}}
  object.Set(Napi::String::New(env, "{{$m.Name}}"), interop::ToJS(env, value.{{$m.Name}}));
{{-    end}}
{{- end}}


{{- /*
--------------------------------------------------------------------------------
-- Interface emits the C++ method implementations that define the given
-- ast.Interface.
-- Note: Most of the actual binding logic lives in the interface wrapper class.
--------------------------------------------------------------------------------
*/ -}}
{{- define "Interface"}}
{{$.Name}}::{{$.Name}}() = default;

{{-  if not (HasAnnotation $ "ManualImplementation")}}
{{$.Name}}* {{$.Name}}::Unwrap(Napi::Object object) {
  auto* wrappers = Wrappers::For(object.Env());
  if (!object.InstanceOf(wrappers->{{$.Name}}_ctor.Value())) {
    return nullptr;
  }
  return Wrappers::W{{$.Name}}::Unwrap(object)->impl.get();
}

Interface<{{$.Name}}> {{$.Name}}::Bind(Napi::Env env, std::unique_ptr<{{$.Name}}>&& impl) {
  auto* wrappers = Wrappers::For(env);
  // Pass in kInternalConstructionMarker to allow this instance to actually be constructed.
  auto object = wrappers->{{$.Name}}_ctor.New({
    Napi::External<void>::New(env, &kInternalConstructionMarker)
  });
  auto* wrapper = Wrappers::W{{$.Name}}::Unwrap(object);
  wrapper->impl = std::move(impl);

{{- /*Add the [SameObject] members as read-only property on the JS object.*/ -}}
{{- range $a := AttributesOf $}}
{{-   if HasAnnotation $a "SameObject"}}
  object.DefineProperty(Napi::PropertyDescriptor::Value(
    "{{$a.Name}}", ToJS(env, wrapper->impl->get{{Title $a.Name}}(env)), napi_default_jsproperty
  ));
{{-   end}}
{{- end}}

  return Interface<{{$.Name}}>(object);
}
{{-  end}}

{{$.Name}}::~{{$.Name}}() = default;
{{ end}}


{{- /*
--------------------------------------------------------------------------------
-- Enum emits the C++ associated functions of the interop type that defines the
-- given ast.Enum
--------------------------------------------------------------------------------
*/ -}}
{{- define "Enum"}}
bool Converter<{{$.Name}}>::FromString(std::string str, {{$.Name}}& out) {
{{-  range $e := $.Values}}
  if (str == {{$e.Value}}) {
    out = {{$.Name}}::{{EnumEntryName $e.Value}};
    return true;
  }
{{-  end}}
  return false;
}

const char* Converter<{{$.Name}}>::ToString({{$.Name}} value) {
  switch (value) {
{{-  range $e := $.Values}}
  case {{$.Name}}::{{EnumEntryName $e.Value}}:
    return {{$e.Value}};
{{-  end}}
  }
  return nullptr;
}

Result Converter<{{$.Name}}>::FromJS(Napi::Env env, Napi::Value value, {{$.Name}}& out) {
  std::string str = value.ToString();
  if (FromString(str, out)) {
    return Success;
  }
  return Error(str + " is not a valid enum value of {{$.Name}}");
}

Napi::Value Converter<{{$.Name}}>::ToJS(Napi::Env env, {{$.Name}} value) {
  switch (value) {
{{-  range $e := $.Values}}
  case {{$.Name}}::{{EnumEntryName $e.Value}}:
    return Napi::String::New(env, {{$e.Value}});
{{-  end}}
  }
  return env.Undefined();
}

std::ostream& operator<<(std::ostream& o, {{$.Name}} value) {
  if (auto* s = Converter<{{$.Name}}>::ToString(value)) {
    return o << s;
  }
  return o << "undefined<{{$.Name}}>";
}

{{end}}
