// 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;
}

extension CompileTarget on Compiler {
  bool get isJS => this == Compiler.dart2js;

  bool get isWasm => this == Compiler.dart2wasm;
}
