// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Test new enhanced enum syntax.

import 'package:expect/expect.dart';

void main() {
  Expect.equals(3, EnumPlain.values.length);
  Expect.identical(EnumPlain.v1, EnumPlain.values[0]);
  Expect.identical(EnumPlain.v2, EnumPlain.values[1]);
  Expect.identical(EnumPlain.v3, EnumPlain.values[2]);

  Expect.equals(3, EnumPlainTrailingComma.values.length);
  Expect.identical(EnumPlainTrailingComma.v1, EnumPlainTrailingComma.values[0]);
  Expect.identical(EnumPlainTrailingComma.v2, EnumPlainTrailingComma.values[1]);
  Expect.identical(EnumPlainTrailingComma.v3, EnumPlainTrailingComma.values[2]);

  Expect.equals(3, EnumNoSemicolon.values.length);
  Expect.identical(EnumNoSemicolon.v1, EnumNoSemicolon.values[0]);
  Expect.identical(EnumNoSemicolon.v2, EnumNoSemicolon.values[1]);
  Expect.identical(EnumNoSemicolon.v3, EnumNoSemicolon.values[2]);
  Expect.type<EnumNoSemicolon<num>>(EnumNoSemicolon.v1);

  Expect.equals(3, EnumPlainSemicolon.values.length);
  Expect.identical(EnumPlainSemicolon.v1, EnumPlainSemicolon.values[0]);
  Expect.identical(EnumPlainSemicolon.v2, EnumPlainSemicolon.values[1]);
  Expect.identical(EnumPlainSemicolon.v3, EnumPlainSemicolon.values[2]);

  Expect.equals(3, EnumPlainTrailingCommaSemicolon.values.length);
  Expect.identical(
    EnumPlainTrailingCommaSemicolon.v1,
    EnumPlainTrailingCommaSemicolon.values[0],
  );
  Expect.identical(
    EnumPlainTrailingCommaSemicolon.v2,
    EnumPlainTrailingCommaSemicolon.values[1],
  );
  Expect.identical(
    EnumPlainTrailingCommaSemicolon.v3,
    EnumPlainTrailingCommaSemicolon.values[2],
  );

  Expect.equals(6, EnumAll.values.length);
  Expect.identical(EnumAll.v1, EnumAll.values[0]);
  Expect.identical(EnumAll.v2, EnumAll.values[1]);
  Expect.identical(EnumAll.v3, EnumAll.values[2]);
  Expect.identical(EnumAll.v4, EnumAll.values[3]);
  Expect.identical(EnumAll.v5, EnumAll.values[4]);
  Expect.identical(EnumAll.v6, EnumAll.values[5]);

  Expect.equals("unnamed", EnumAll.v1.constructor);
  Expect.equals("unnamed", EnumAll.v2.constructor);
  Expect.equals("unnamed", EnumAll.v3.constructor);
  Expect.equals("named", EnumAll.v4.constructor);
  Expect.equals("renamed", EnumAll.v5.constructor);
  Expect.equals("unnamed", EnumAll.v6.constructor);

  Expect.type<EnumAll<num, num>>(EnumAll.v1);
  Expect.type<EnumAll<num, int>>(EnumAll.v2);
  Expect.type<EnumAll<int, int>>(EnumAll.v3);
  Expect.type<EnumAll<int, int>>(EnumAll.v4);
  Expect.type<EnumAll<int, int>>(EnumAll.v5);
  Expect.type<EnumAll<num, num>>(EnumAll.v6);

  // Access static members.
  Expect.identical(EnumAll.v3, EnumAll.sConst);
  Expect.identical(EnumAll.v3, EnumAll.sFinal);

  Expect.throws(() => EnumAll.sLateFinal);
  EnumAll.sLateFinal = EnumAll.v1;
  Expect.identical(EnumAll.v1, EnumAll.sLateFinal);
  Expect.throws(() => EnumAll.sLateFinal = EnumAll.v1);

  Expect.identical(EnumAll.v3, EnumAll.sFinal);

  Expect.throws(() => EnumAll.sLateVar);
  EnumAll.sLateVar = EnumAll.v1;
  Expect.identical(EnumAll.v1, EnumAll.sLateVar);
  EnumAll.sLateVar = EnumAll.v3;
  Expect.identical(EnumAll.v3, EnumAll.sLateVar);
  Expect.identical(EnumAll.v3, EnumAll.sLateVarInit);
  Expect.isNull(EnumAll.sVar);
  Expect.identical(EnumAll.v3, EnumAll.sVarInit);

  Expect.identical(EnumAll.v3, EnumAll.staticGetSet);
  EnumAll.staticGetSet = EnumAll.v5;
  Expect.equals(42, EnumAll.staticMethod());

  Expect.identical(EnumAll.v3, EnumAll<num, num>.factory(2));
  Expect.identical(EnumAll.v3, EnumAll<num, num>.refactory(2));

  // Access static members through typedef.
  Expect.identical(EnumAll.v3, TypeDefAll.sConst);
  Expect.identical(EnumAll.v3, TypeDefAll.sFinal);
  Expect.identical(EnumAll.v1, TypeDefAll.sLateFinal);
  Expect.identical(EnumAll.v3, TypeDefAll.sLateFinalInit);

  Expect.identical(EnumAll.v3, TypeDefAll.staticGetSet);
  TypeDefAll.staticGetSet = EnumAll.v5;
  Expect.equals(42, TypeDefAll.staticMethod());

  Expect.identical(EnumAll.v3, TypeDefAll.factory(2));
  Expect.identical(EnumAll.v3, TypeDefAll.refactory(2));

  // Access instance members.
  Expect.equals(0, EnumAll.v1.instanceGetSet);
  EnumAll.v1.instanceGetSet = 0.5;
  Expect.equals(0, EnumAll.v1.instanceMethod());
  Expect.identical(EnumAll.v4, EnumAll.v3 ^ EnumAll.v2);

  Expect.equals(
    "EnumAll.v1:EnumMixin<$num>:ObjectMixin:this",
    EnumAll.v1.thisAndSuper(),
  );

  // Which can reference type parameters.
  Expect.isTrue(EnumAll.v2.test(2)); // does `is T` with `T` being `int`.
  Expect.isFalse(EnumAll.v2.test(2.5));

  // Including `call`.
  Expect.equals(42, EnumAll.v1<int>(42));
  Expect.equals(42, EnumAll.v1(42));
  // Also as tear-off.
  Function eaf1 = EnumAll.v1;
  Expect.type<T Function<T>(T)>(eaf1);
  Function eaf2 = EnumAll.v1<String>;
  Expect.type<String Function(String)>(eaf2);

  // Instance members shadow extensions.
  Expect.equals("not extension", EnumAll.v1.notExtension);
  // But you can call extension members if there is no conflict.
  Expect.equals("extension", EnumAll.v1.extension);

  // The `index` implementation is inherited from the `Enum` implementing
  // superclass, and the `toString` implementation is overridden, but
  // available via `realToString`.
  Expect.equals(0, OverrideEnum.v1.index);
  Expect.equals(1, OverrideEnum.v2.index);
  Expect.equals(0, OverrideEnum.v1.superIndex);
  Expect.equals(1, OverrideEnum.v2.superIndex);
  Expect.equals("FakeString", OverrideEnum.v1.toString());
  Expect.equals("FakeString", OverrideEnum.v2.toString());
  Expect.equals("OverrideEnum.v1", OverrideEnum.v1.realToString());
  Expect.equals("OverrideEnum.v2", OverrideEnum.v2.realToString());

  // Enum elements are always distinct, even if their state doesn't differ.
  Expect.notIdentical(Canonical.v1, Canonical.v2, "Canonical - type only");
  Expect.notIdentical(Canonical.v2, Canonical.v3, "Canonical - no difference");

  Expect.identical(SelfRefEnum.e1, SelfRefEnum.e2.previous, "SelfRef.prev");
}

// Original syntax still works, without semicolon after values.
enum EnumPlain { v1, v2, v3 }

// Also with trailing comma.
enum EnumPlainTrailingComma { v1, v2, v3 }

// Also if using type parameters, mixins or interfaces.
// It only matters whether there is something after the values.
enum EnumNoSemicolon<T extends num> with ObjectMixin implements Interface {
  v1,
  v2,
  v3,
}

// Allows semicolon after values, even when not needed.
// Without trailing comma.
enum EnumPlainSemicolon { v1, v2, v3 }

// With trailing comma.
enum EnumPlainTrailingCommaSemicolon { v1, v2, v3 }

// Full syntax, with every possible option.
@EnumAll.v1
@EnumAll.sConst
enum EnumAll<S extends num, T extends num>
    with GenericEnumMixin<T>, ObjectMixin
    implements Interface, GenericInterface<S> {
  @v1
  @v2
  v1,
  @EnumAll.v2
  v2(y: 2),
  @sConst
  v3<int, int>(y: 2),
  v4.named(1, y: 2),
  v5<int, int>.renamed(1, y: 2),
  v6.new();

  /// Static members.
  ///
  /// Any kind of static variable.
  static const sConst = v3;
  static final sFinal = v3;
  static late final EnumAll sLateFinal;
  static late final sLateFinalInit = v3;
  static late EnumAll sLateVar;
  static late var sLateVarInit = v3;
  static EnumAll? sVar;
  static EnumAll sVarInit = v3;

  /// Static getters, setters and methods
  static EnumAll<int, int> get staticGetSet => v3;
  static set staticGetSet(EnumAll<int, int> _) {}
  static int staticMethod() => 42;

  // Constructors.
  // Generative, non-redirecting, unnamed.
  const EnumAll({T? y})
    : constructor = "unnamed",
      this.x = 0 as S,
      y = y ?? (0 as T);
  // Generative, non-redirecting, named.
  const EnumAll.named(this.x, {T? y, String? constructor})
    : constructor = constructor ?? "named",
      y = y ?? (0 as T);
  // Generative, redirecting.
  const EnumAll.renamed(S x, {T? y})
    : this.named(x, y: y, constructor: "renamed");
  // Factory, non-redirecting.
  factory EnumAll.factory(int index) => values[index] as EnumAll<S, T>;
  // Factory, redirecting (only to other factory constructor).
  factory EnumAll.refactory(int index) = EnumAll<S, T>.factory;

  // Cannot have factory constructors redirecting to generative constructors.
  // (Nothing can refer to generative constructors except redirecting generative
  // constructors and the implicit element creation expressions.)
  // Cannot have const factory constructor, because they *must* redirect to
  // generative constructors.
  // Cannot have `super`-constructor invocations in initializer lists.

  // Instance members.

  // Instance variables must be final and non-late because of const constructor.
  final String constructor;
  final S x;
  final num y;

  // Getters, setters, methods and operators.
  S get instanceGetSet => x;
  set instanceGetSet(S _) {}
  S instanceMethod() => x;
  EnumAll<num, num> operator ^(EnumAll<num, num> other) {
    var newIndex = index ^ other.index;
    if (newIndex > 4) newIndex = 4;
    return values[newIndex]; // Can refer to `values`.
  }

  // Can access `this` and `super` in an instance method.
  String thisAndSuper() => "${super.toString()}:${this.toString()}";

  // Can be callable.
  T call<T>(T value) => value;

  // Can have an `index` setter.
  set index(int value) {}

  // Instance members shadow extensions.
  String get notExtension => "not extension";

  String toString() => "this";
}

extension EnumAllExtension on EnumAll {
  String get notExtension {
    Expect.fail("Unreachable");
    return "not";
  }

  String get extension => "extension";
}

typedef TypeDefAll = EnumAll<num, num>;

// Can have no unnamed constructor.
enum EnumNoUnnamedConstructor {
  v1.named(1),
  v2.named(2);

  final int x;
  const EnumNoUnnamedConstructor.named(this.x);
}

enum NewNamedConstructor {
  v1;

  const NewNamedConstructor.new();
}

// Can have an unnamed factory constructor.
enum EnumFactoryUnnamedConstructor {
  v1.named(1),
  v2.named(2);

  final int x;
  factory EnumFactoryUnnamedConstructor() => v1;
  const EnumFactoryUnnamedConstructor.named(this.x);
}

// Elements which do not differ in public state are still different.
// Ditto if only differing in type arguments.
enum Canonical<T> {
  v1<int>(1),
  v2<num>(1),
  v3<num>(1);

  final T value;
  const Canonical(this.value);
}

// Both `toString` and `index` are inherited from superclass.
enum OverrideEnum {
  v1,
  v2;

  // Cannot override index
  int get superIndex => super.index;
  String toString() => "FakeString";
  String realToString() => super.toString();
}

// An enum value expression *can* reference another enum value.
enum SelfRefEnum {
  e1(null),
  e2(e1);

  final SelfRefEnum? previous;
  const SelfRefEnum(this.previous);
}

// --------------------------------------------------------------------
// Helper declarations

mixin ObjectMixin on Object {
  String toString() => "${super.toString()}:ObjectMixin";
}

mixin EnumMixin on Enum {
  String toString() => "${super.toString()}:EnumMixin";
}

mixin GenericObjectMixin<T> on Object {
  bool test(Object o) => o is T;
  String toString() => "${super.toString()}:ObjectMixin<$T>";
}

mixin GenericEnumMixin<T> on Enum {
  bool test(Object o) => o is T;
  String toString() => "${super.toString()}:EnumMixin<$T>";
}

abstract class Interface {}

abstract class GenericInterface<T> {
  // Implemented by mixins.
  bool test(Object o);
}
