// Copyright (c) 2023, 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.

/// All the Dart compilers supported by the test runner.
enum Compiler {
  /// The production Dart to Javascript compiler (whole world, optimizing).
  dart2js('Dart2Js', 'dart2js'),

  /// Experimental Dart to Wasm compiler.
  dart2wasm('Dart2WASM', 'dart2wasm'),

  /// Compiles dart code to a native executable.
  exe('Exe', 'exe'),

  /// The standard compiler for vm tests, compiles tests to kernel before
  /// running them on the VM.
  kernel('Kernel', 'kernel'),

  /// Runs tests directly from source, with no precompilation.
  source('Source', 'source');

  /// The compilers that are supported by the test runner by default.
  static const List<Compiler> builtIn = [
    Compiler.dart2js,
    Compiler.dart2wasm,
    Compiler.exe,
    Compiler.kernel,
    Compiler.source,
  ];

  /// The human-friendly name of the compiler.
  final String name;

  /// The identifier used to look up the compiler.
  final String identifier;

  const Compiler(this.name, this.identifier);

  /// Converts a JSON-safe representation generated by [serialize] back into a
  /// [Compiler].
  ///
  /// Note that custom [Compiler] implementations are not supported.
  factory Compiler.deserialize(Object serialized) => builtIn
      .firstWhere((compiler) => compiler.identifier == serialized as String);

  /// Converts [this] into a JSON-safe object that can be converted back to a
  /// [Compiler] using [Compiler.deserialize].
  Object serialize() => identifier;

  @override
  String toString() => name;
}
