// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// clang-format off

// This file has been auto-generated by bindings/code_generator_cobalt.py. DO NOT MODIFY!
// Auto-generated from template: bindings/mozjs45/templates/dictionary-conversion.cc.template

#include "mozjs_gen_type_conversion.h"

#include "cobalt/bindings/testing/dictionary_with_dictionary_member.h"

#include "cobalt/script/exception_state.h"
#include "third_party/mozjs-45/js/src/jsapi.h"
#include "cobalt/bindings/testing/test_dictionary.h"

using cobalt::bindings::testing::DictionaryWithDictionaryMember;
using cobalt::bindings::testing::TestDictionary;

namespace cobalt {
namespace script {
namespace mozjs {

void ToJSValue(
    JSContext* context,
    const DictionaryWithDictionaryMember& in_dictionary,
    JS::MutableHandleValue out_value) {
  // Create a new object that will hold the dictionary values.
  JS::RootedObject dictionary_object(
      context, JS_NewObject(context, nullptr));
  const int kPropertyAttributes = JSPROP_ENUMERATE;
  if (in_dictionary.has_nested_dictionary()) {
    JS::RootedValue member_value(context);
    ToJSValue(context, in_dictionary.nested_dictionary(), &member_value);
    if (!JS_DefineProperty(context, dictionary_object,
                           "nestedDictionary",
                           member_value, kPropertyAttributes, nullptr, nullptr)) {
      // Some internal error occurred.
      NOTREACHED();
      return;
    }
  }
  out_value.setObject(*dictionary_object);
}

void FromJSValue(JSContext* context, JS::HandleValue value,
                 int conversion_flags, ExceptionState* exception_state,
                 DictionaryWithDictionaryMember* out_dictionary) {
  DCHECK_EQ(0, conversion_flags) << "Unexpected conversion flags.";
  MozjsExceptionState* mozjs_exception_state = base::polymorphic_downcast<MozjsExceptionState*>(exception_state);
  DCHECK(!mozjs_exception_state->is_exception_set());

  // https://heycam.github.io/webidl/#es-dictionary

  if (value.isUndefined() || value.isNull()) {
    // The default constructor will assign appropriate values to dictionary
    // members with default values and leave the others unset.
    *out_dictionary = DictionaryWithDictionaryMember();
    return;
  }
  if (!value.isObject()) {
    // 1. If Type(V) is not Undefined, Null or Object, then throw a TypeError.
    exception_state->SetSimpleException(kNotObjectType);
    return;
  }
  JS::RootedObject dictionary_object(context, &value.toObject());
  JS::RootedValue nested_dictionary(context);
  if (!JS_GetProperty(context, dictionary_object,
                      "nestedDictionary",
                      &nested_dictionary)) {
    exception_state->SetSimpleException(kSimpleError);
    return;
  }
  if (!nested_dictionary.isUndefined()) {
    TestDictionary converted_value;
    FromJSValue(context,
                nested_dictionary,
                kNoConversionFlags,
                exception_state,
                &converted_value);
    if (context->isExceptionPending()) {
      return;
    }
    out_dictionary->set_nested_dictionary(converted_value);
  }
}

}  // namespace mozjs
}  // namespace script
}  // namespace cobalt

