
// Copyright 2020 The Cobalt Authors. 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/v8c/templates/enumeration-conversion.cc.template

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

#include "v8c_gen_type_conversion.h"
#include "base/logging.h"
#include "cobalt/script/exception_state.h"
#include "cobalt/script/v8c/helpers.h"
#include "v8/include/v8.h"

using cobalt::bindings::testing::TestEnum;

namespace cobalt {
namespace script {
namespace v8c {

void ToJSValue(
    v8::Isolate* isolate,
    TestEnum in_enum,
    v8::Local<v8::Value>* out_value) {
  switch (in_enum) {
    case cobalt::bindings::testing::kTestEnumAlpha:
      ToJSValue(isolate, std::string("alpha"), out_value);
      return;
    case cobalt::bindings::testing::kTestEnumBeta:
      ToJSValue(isolate, std::string("beta"), out_value);
      return;
    case cobalt::bindings::testing::kTestEnumGamma:
      ToJSValue(isolate, std::string("gamma"), out_value);
      return;
    case cobalt::bindings::testing::kTestEnumEnumWithDashes:
      ToJSValue(isolate, std::string("enum-with-dashes"), out_value);
      return;
    case cobalt::bindings::testing::kTestEnumEnumWithSpaces:
      ToJSValue(isolate, std::string("enum with spaces"), out_value);
      return;
    case cobalt::bindings::testing::kTestEnumTerribleEnum:
      ToJSValue(isolate, std::string("terrible----enum"), out_value);
      return;
    case cobalt::bindings::testing::kTestEnumThisIsATerribleEnum:
      ToJSValue(isolate, std::string("this is a terrible @#$%#$% enum"), out_value);
      return;
    default:
      NOTREACHED();
      *out_value = v8::Null(isolate);
  }
}

void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 TestEnum* out_enum) {
  DCHECK_EQ(0, conversion_flags) << "Unexpected conversion flags.";
  // JSValue -> IDL enum algorithm described here:
  // http://heycam.github.io/webidl/#es-enumeration
  // 1. Let S be the result of calling ToString(V).
  v8::Local<v8::Context> context = isolate->GetCurrentContext();
  v8::MaybeLocal<v8::String> maybe_string = value->ToString(context);
  v8::Local<v8::String> string;
  if (!maybe_string.ToLocal(&string)) {
    exception_state->SetSimpleException(cobalt::script::kConvertToEnumFailed);
    return;
  }

  bool match = false;
// 3. Return the enumeration value of type E that is equal to S.
 if (
      NewInternalString(isolate, "alpha")->Equals(context, value).ToChecked())
  {
    *out_enum = cobalt::bindings::testing::kTestEnumAlpha;
  }
 else  if (
      NewInternalString(isolate, "beta")->Equals(context, value).ToChecked())
  {
    *out_enum = cobalt::bindings::testing::kTestEnumBeta;
  }
 else  if (
      NewInternalString(isolate, "gamma")->Equals(context, value).ToChecked())
  {
    *out_enum = cobalt::bindings::testing::kTestEnumGamma;
  }
 else  if (
      NewInternalString(isolate, "enum-with-dashes")->Equals(context, value).ToChecked())
  {
    *out_enum = cobalt::bindings::testing::kTestEnumEnumWithDashes;
  }
 else  if (
      NewInternalString(isolate, "enum with spaces")->Equals(context, value).ToChecked())
  {
    *out_enum = cobalt::bindings::testing::kTestEnumEnumWithSpaces;
  }
 else  if (
      NewInternalString(isolate, "terrible----enum")->Equals(context, value).ToChecked())
  {
    *out_enum = cobalt::bindings::testing::kTestEnumTerribleEnum;
  }
 else  if (
      NewInternalString(isolate, "this is a terrible @#$%#$% enum")->Equals(context, value).ToChecked())
  {
    *out_enum = cobalt::bindings::testing::kTestEnumThisIsATerribleEnum;
  }
  else {
    // 2. If S is not one of E's enumeration values, then throw a TypeError.
    exception_state->SetSimpleException(cobalt::script::kConvertToEnumFailed);
    return;
  }
}

}  // namespace v8c
}  // namespace script
}  // namespace cobalt
