// Generated from "jsenum/Main.java"
@file:Suppress(
 "ALWAYS_NULL",
 "PARAMETER_NAME_CHANGED_ON_OVERRIDE",
 "SENSELESS_COMPARISON",
 "UNCHECKED_CAST",
 "UNNECESSARY_LATEINIT",
 "UNNECESSARY_NOT_NULL_ASSERTION",
 "UNREACHABLE_CODE",
 "UNUSED_ANONYMOUS_PARAMETER",
 "UNUSED_PARAMETER",
 "UNUSED_VARIABLE",
 "USELESS_CAST",
 "VARIABLE_IN_SINGLETON_WITHOUT_THREAD_LOCAL",
 "VARIABLE_WITH_REDUNDANT_INITIALIZER",
 "REDUNDANT_ELSE_IN_WHEN")

package jsenum

import javaemul.lang.*
import java.util.ArrayList
import java.util.Arrays
import java.util.Optional
import jsinterop.annotations.JsEnum
import jsinterop.annotations.JsFunction
import jsinterop.annotations.JsMethod
import jsinterop.annotations.JsProperty
import kotlin.Any
import kotlin.Array
import kotlin.Boolean
import kotlin.Comparable
import kotlin.Int
import kotlin.String
import kotlin.Suppress
import kotlin.arrayOf
import kotlin.arrayOfNulls
import kotlin.collections.MutableList
import kotlin.jvm.JvmField
import kotlin.jvm.JvmStatic
import kotlin.run

open class Main {
 companion object {
  @JvmStatic
  fun testJsEnumSwitch() {
   var comparableJsEnum: ComparableJsEnum? = if (ComparableJsEnum.ONE.getValue() == 1) ComparableJsEnum.TWO else null
   when (comparableJsEnum!!) {
    ComparableJsEnum.TWO -> {}
    else -> {}
   }
   val comparable: Comparable<Any>? = comparableJsEnum as Comparable<Any>?
   comparableJsEnum = comparable as ComparableJsEnum?
   var intJsEnum: IntJsEnum? = if (IntJsEnum.ELEVEN.getValue() == 10) IntJsEnum.ELEVEN else null
   when (intJsEnum!!) {
    IntJsEnum.TWENTY -> {}
    else -> {}
   }
   val o: Any? = intJsEnum
   intJsEnum = o as IntJsEnum?
   val equal: Boolean = intJsEnum === IntJsEnum.TWENTY
   var isInstance: Boolean = intJsEnum is IntJsEnum
   isInstance = intJsEnum is Comparable<*>
   val stringJsEnum: StringJsEnum? = if (StringJsEnum.ONE.getValue() === "10") StringJsEnum.THREE else null
   when (stringJsEnum!!) {
    StringJsEnum.ONE -> {}
    else -> {}
   }
   NativeStringEnum.ONE.compareTo(
    NativeStringEnum.THREE,
   )
   NativeStringEnum.ONE.equals(
    NativeStringEnum.THREE,
   )
   val supplier: Supplier<ComparableJsEnum?> = Supplier {
    return@Supplier ComparableJsEnum.ONE
   }
   val consummer: Consumer<ComparableJsEnum?> = Consumer { e: ComparableJsEnum? ->
    e!!.ordinal
   }
   Main.acceptsJsFunctionSupplier(
    JsFunctionSuppiler {
     return@JsFunctionSuppiler ComparableJsEnum.ONE
    },
   )
   Main.acceptsSupplierOfSupplier(
    Supplier {
     return@Supplier Supplier {
      return@Supplier ComparableJsEnum.ONE
     }
    },
   )
   Main.acceptsJsFunctionParameterizedByJsEnum(
    SpecializedJsFunction { e_1: ComparableJsEnum? ->
     return@SpecializedJsFunction e_1
    },
   )
  }

  @JvmStatic
  private fun testExhaustiveJsEnumSwitchExpression() {
   val comparableJsEnum: ComparableJsEnum? = if (ComparableJsEnum.ONE.getValue() == 1) ComparableJsEnum.TWO else null
   val i: Int = run {
    when (comparableJsEnum!!) {
     ComparableJsEnum.TWO -> {
      return@run 2
     }
     ComparableJsEnum.ONE -> {
      return@run 1
     }
     ComparableJsEnum.ZERO -> {
      return@run 0
     }
    }
   }
  }

  @JvmStatic
  private fun testJsEnumAutoboxingSpecialMethods() {
   val stringJsEnum: StringJsEnum = StringJsEnum.ONE
   val nullStringJsEnum: StringJsEnum? = null
   val jsEnum: ComparableJsEnum = ComparableJsEnum.ONE
   val nullJsEnum: ComparableJsEnum? = null
   val o: Any = ComparableJsEnum.ONE
   StringJsEnum.ONE.equals(
    StringJsEnum.THREE,
   )
   StringJsEnum.ONE.equals(stringJsEnum)
   StringJsEnum.ONE.equals(nullStringJsEnum)
   StringJsEnum.ONE.equals(null)
   StringJsEnum.ONE.equals(o)
   o.equals(
    StringJsEnum.THREE,
   )
   ComparableJsEnum.ONE.compareTo(
    ComparableJsEnum.ZERO,
   )
   ComparableJsEnum.ONE.compareTo(
    null!!,
   )
   ComparableJsEnum.ONE.equals(
    ComparableJsEnum.ZERO,
   )
   ComparableJsEnum.ONE.equals(jsEnum)
   ComparableJsEnum.ONE.equals(nullJsEnum)
   ComparableJsEnum.ONE.equals(null)
   ComparableJsEnum.ONE.equals(o)
   o.equals(
    ComparableJsEnum.ZERO,
   )
   StringJsEnum.ONE.equals(jsEnum)
   Main.boxingPassthrough<ComparableJsEnum?>(
    ComparableJsEnum.ONE,
   )!!.equals(
    Main.boxingPassthrough<ComparableJsEnum?>(
     ComparableJsEnum.ONE,
    ),
   )
   Main.boxingPassthrough<ComparableJsEnum?>(
    ComparableJsEnum.ONE,
   )!!.equals(
    Main.boxingPassthrough<StringJsEnum?>(
     StringJsEnum.ONE,
    ),
   )
  }

  @JvmStatic
  private fun acceptsJsFunctionSupplier(supplier: JsFunctionSuppiler<ComparableJsEnum?>?) {}

  @JvmStatic
  private fun acceptsSupplierOfSupplier(supplier: Supplier<Supplier<ComparableJsEnum?>?>?) {}

  @JvmStatic
  private fun acceptsJsFunctionParameterizedByJsEnum(supplier: SpecializedJsFunction<ComparableJsEnum?>?) {}

  @JvmStatic
  private fun testReturnsAndParameters() {
   val returnedValue: ComparableJsEnum? = Main.returnsJsEnum()
   val returnedNullValue: ComparableJsEnum? = Main.returnsNullJsEnum()
   Main.takesJsEnum(
    ComparableJsEnum.ONE,
   )
  }

  @JvmStatic
  private fun returnsJsEnum(): ComparableJsEnum? {
   return ComparableJsEnum.ONE
  }

  @JvmStatic
  private fun returnsNullJsEnum(): ComparableJsEnum? {
   return null
  }

  @JvmStatic
  private fun takesJsEnum(value: ComparableJsEnum?) {}

  @JvmStatic
  private fun testBoxUnboxWithTypeInference() {
   val templatedField: TemplatedField<ComparableJsEnum?> = TemplatedField<ComparableJsEnum?>(
    ComparableJsEnum.ONE,
   )
   var unboxed: ComparableJsEnum? = templatedField.getValue_pp_jsenum()
   unboxed = templatedField.value_pp_jsenum
   templatedField.value_pp_jsenum = ComparableJsEnum.ONE
   Arrays.asList<ComparableJsEnum>(
    ComparableJsEnum.ONE,
   )
   templatedField.getValue_pp_jsenum()!!.ordinal
   val b: Boolean = ComparableJsEnum.ONE === Main.boxingPassthrough<ComparableJsEnum?>(
    ComparableJsEnum.ONE,
   )
  }

  @JvmStatic
  private fun <T> boxingPassthrough(t: T): T {
   return t
  }

  @JvmStatic
  internal fun boxingWithGenerics_pp_jsenum() {
   Foo<Any?>(
    Optional.of<IntJsEnum>(
     IntJsEnum.MINUSONE,
    ),
   )
  }

  @JvmStatic
  private fun <T> varargsConsumer(vararg args: T): T {
   val args_1: Array<T>? = args as Array<T>?
   return args_1!![0]
  }

  @JvmStatic
  private fun testVarargs() {
   Main.varargsConsumer<SomeJsEnum?>(
    SomeJsEnum.A,
    SomeJsEnum.A,
   )
   val consumer: Consumer<SomeJsEnum?> = Consumer { arg0: SomeJsEnum? ->
    Main.varargsConsumer<SomeJsEnum?>(arg0)
   }
  }

  @JvmStatic
  private fun testNonNativeJsEnumArrays() {
   val arr: Array<IntJsEnum?> = arrayOf<IntJsEnum?>(IntJsEnum.MINUSONE, IntJsEnum.TWENTY)
   val b1: Boolean = arr[0] === IntJsEnum.MINUSONE
   val b2: Boolean = arr[1] === IntJsEnum.TWENTY
   var obj: Any? = arr[0]
   val v: IntJsEnum? = arr[0]
   val arr2: Array<IntJsEnum?> = arrayOfNulls<IntJsEnum>(2)
   arr2[0] = IntJsEnum.MINUSONE
   arr2[1] = IntJsEnum.TWENTY
   val nestedArr: Array<Array<IntJsEnum?>?> = arrayOf<Array<IntJsEnum?>?>(arrayOf<IntJsEnum?>(IntJsEnum.MINUSONE))
   nestedArr[0] = arrayOf<IntJsEnum?>(IntJsEnum.TWENTY)
   val arrayWithNull: Array<IntJsEnum?> = arrayOf<IntJsEnum?>(null)
   arrayWithNull[0] = null
   val list: MutableList<IntJsEnum?> = ArrayList<IntJsEnum>() as MutableList<IntJsEnum?>
   obj = list.toArray()
   Main.nonNativeJsEnumVarargs(
    IntJsEnum.MINUSONE,
    IntJsEnum.TWENTY,
   )
   Main.nonNativeJsEnumArrayVarargs(
    arrayOf<IntJsEnum?>(IntJsEnum.MINUSONE),
    arrayOf<IntJsEnum?>(IntJsEnum.TWENTY),
   )
   Main.tVarargs<IntJsEnum?>(
    IntJsEnum.MINUSONE,
    IntJsEnum.TWENTY,
   )
  }

  @JvmStatic
  private fun nonNativeJsEnumVarargs(vararg values: IntJsEnum?) {
   val values_1: Array<IntJsEnum?>? = values as Array<IntJsEnum?>?
   val v: IntJsEnum? = values_1!![0]
  }

  @JvmStatic
  private fun nonNativeJsEnumArrayVarargs(vararg values: Array<IntJsEnum?>?) {
   val values_1: Array<Array<IntJsEnum?>?>? = values as Array<Array<IntJsEnum?>?>?
   val v: Array<IntJsEnum?>? = values_1!![0]
  }

  @JvmStatic
  private fun <T> tVarargs(vararg values: T) {
   val values_1: Array<T>? = values as Array<T>?
   val v: T? = values_1!![0]
  }

  @JvmStatic
  private fun testNonNativeStringJsEnumArrays() {
   val arr: Array<StringJsEnum?> = arrayOf<StringJsEnum?>(StringJsEnum.ONE, StringJsEnum.THREE)
   val b1: Boolean = arr[0] === StringJsEnum.ONE
   val obj: Any? = arr[0]
   val v: StringJsEnum? = arr[0]
   val arr2: Array<StringJsEnum?> = arrayOfNulls<StringJsEnum>(2)
   arr2[0] = StringJsEnum.ONE
   val nestedArr: Array<Array<StringJsEnum?>?> = arrayOf<Array<StringJsEnum?>?>(arrayOf<StringJsEnum?>(StringJsEnum.ONE))
   val arrayWithNull: Array<StringJsEnum?> = arrayOf<StringJsEnum?>(null)
   arrayWithNull[0] = null
  }

  @JvmStatic
  private fun testNativeJsEnumArrays() {
   val arr: Array<NativeStringEnum?> = arrayOf<NativeStringEnum?>(NativeStringEnum.ONE, NativeStringEnum.THREE)
   val b1: Boolean = arr[0] === NativeStringEnum.ONE
   val arr2: Array<NativeStringEnum?> = arrayOfNulls<NativeStringEnum>(2)
   arr2[0] = NativeStringEnum.ONE
   val nestedArr: Array<Array<NativeStringEnum?>?> = arrayOf<Array<NativeStringEnum?>?>(arrayOf<NativeStringEnum?>(NativeStringEnum.ONE))
   nestedArr[0] = arrayOf<NativeStringEnum?>(NativeStringEnum.THREE)
   val arrayWithNull: Array<NativeStringEnum?> = arrayOf<NativeStringEnum?>(null)
   arrayWithNull[0] = null
  }
 }

 fun interface Supplier<T> {
  fun get(): T
 }

 fun interface Consumer<T> {
  fun accept(t: T)
 }

 @JsEnum
 enum class ComparableJsEnum {
  ZERO,
  ONE,
  TWO;

  fun getValue(): Int {
   return this.ordinal
  }
 }

 @JsEnum(hasCustomValue = true)
 enum class IntJsEnum {
  MINUSONE(-1),
  TWENTY(20),
  ELEVEN(11);

  private var value: Int = 0

  fun getValue(): Int {
   return this.value
  }

  constructor(value: Int) {
   this.value = value
  }
 }

 @JsEnum(hasCustomValue = true)
 enum class StringJsEnum {
  ONE("ONE"),
  THREE("THREE");

  private var value: String? = null

  fun getValue(): String? {
   return this.value
  }

  constructor(value: String?) {
   this.value = value
  }
 }

 @JsEnum(hasCustomValue = true)
 enum class NonNullableStringJsEnum {
  ONE("ONE"),
  THREE("THREE");

  private var value: String

  fun getValue(): String? {
   return this.value
  }

  constructor(value: String?) {
   this.value = value!!
  }
 }

 @JsEnum(name = "NonNullableStringJsEnum", namespace = "jsenum.Main", isNative = true)
 enum class NativeStringEnum {
  ONE,
  THREE;
 }

 @JsFunction
 fun interface JsFunctionSuppiler<T> {
  fun get(): T
 }

 @JsFunction
 fun interface SpecializedJsFunction<T> {
  fun get(value: T): T
 }

 open class TemplatedField<T> {
  @JvmField
  internal var value_pp_jsenum: T

  internal constructor(value: T) {
   this.value_pp_jsenum = value
  }

  internal open fun getValue_pp_jsenum(): T {
   return this.value_pp_jsenum
  }
 }

 open class Foo<T> {
  internal constructor(c: Optional<IntJsEnum>?)
 }

 @JsEnum
 enum class JsEnumWithRenamedProperties {
  @JsProperty(name = "NAUGHT")
  ZERO,
  ONE,
  TWO;

  fun getValue(): Int {
   return this.ordinal
  }
 }

 open class SupplierConsumerImpl<T> internal constructor(): Supplier<T>, Consumer<T> {
  override fun accept(t: T) {}

  override fun get(): T {
   return null as T
  }
 }

 interface ComparableJsEnumSupplierConsumer: Supplier<ComparableJsEnum?>, Consumer<ComparableJsEnum?> {
  @JsMethod
  override fun get(): ComparableJsEnum?

  override fun accept(e: ComparableJsEnum?)
 }

 open class ComparableJsEnumSupplierConsumerImpl internal constructor(): SupplierConsumerImpl<ComparableJsEnum?>(), ComparableJsEnumSupplierConsumer

 open class ComparableJsEnumSupplierConsumerImplWithOverrides internal constructor(): SupplierConsumerImpl<ComparableJsEnum?>(), ComparableJsEnumSupplierConsumer {
  override fun accept(t: ComparableJsEnum?) {}

  override fun get(): ComparableJsEnum? {
   return null
  }
 }

 @JsEnum
 enum class SomeJsEnum {
  A;
 }

 open class BaseVarargs<T> {
  internal constructor(vararg args: T) {
   val args_1: Array<T>? = args as Array<T>?
  }
 }

 open class SubtypeVarargs: BaseVarargs<SomeJsEnum?> {
  internal constructor(): super(
   SomeJsEnum.A,
   SomeJsEnum.A,
  )
 }

 open class SubtypeImplicitVarargs internal constructor(): BaseVarargs<SomeJsEnum?>()
}
