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

// TODO(nweiz): support pluggable platforms.
/// An enum of all platforms on which tests can run.
class TestPlatform {
  // When adding new platforms, be sure to update the baseline and derived
  // variable tests in test/backend/platform_selector/evaluate_test.

  /// The command-line Dart VM.
  static const TestPlatform vm = const TestPlatform("VM", "vm", isDartVM: true);

  /// Dartium.
  static const TestPlatform dartium = const TestPlatform("Dartium", "dartium",
      isBrowser: true, isBlink: true, isDartVM: true);

  /// Dartium content shell.
  static const TestPlatform contentShell = const TestPlatform(
      "Dartium Content Shell", "content-shell",
      isBrowser: true, isBlink: true, isDartVM: true, isHeadless: true);

  /// Google Chrome.
  static const TestPlatform chrome = const TestPlatform("Chrome", "chrome",
      isBrowser: true, isJS: true, isBlink: true);

  /// PhantomJS.
  static const TestPlatform phantomJS = const TestPlatform(
      "PhantomJS", "phantomjs",
      isBrowser: true, isJS: true, isBlink: true, isHeadless: true);

  /// Mozilla Firefox.
  static const TestPlatform firefox =
      const TestPlatform("Firefox", "firefox", isBrowser: true, isJS: true);

  /// Apple Safari.
  static const TestPlatform safari =
      const TestPlatform("Safari", "safari", isBrowser: true, isJS: true);

  /// Microsoft Internet Explorer.
  static const TestPlatform internetExplorer = const TestPlatform(
      "Internet Explorer", "ie",
      isBrowser: true, isJS: true);

  /// The command-line Node.js VM.
  static const TestPlatform nodeJS =
      const TestPlatform("Node.js", "node", isJS: true);

  /// The platforms that are supported by the test runner by default.
  static const List<TestPlatform> builtIn = const [
    TestPlatform.vm,
    TestPlatform.dartium,
    TestPlatform.contentShell,
    TestPlatform.chrome,
    TestPlatform.phantomJS,
    TestPlatform.firefox,
    TestPlatform.safari,
    TestPlatform.internetExplorer,
    TestPlatform.nodeJS
  ];

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

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

  /// The parent platform that this is based on, or `null` if there is no
  /// parent.
  final TestPlatform parent;

  /// Returns whether this is a child of another platform.
  bool get isChild => parent != null;

  /// Whether this platform runs the Dart VM in any capacity.
  final bool isDartVM;

  /// Whether this platform is a browser.
  final bool isBrowser;

  /// Whether this platform runs Dart compiled to JavaScript.
  final bool isJS;

  /// Whether this platform uses the Blink rendering engine.
  final bool isBlink;

  /// Whether this platform has no visible window.
  final bool isHeadless;

  /// Returns the platform this is based on, or [this] if it's not based on
  /// anything.
  ///
  /// That is, returns [parent] if it's non-`null` or [this] if it's `null`.
  TestPlatform get root => parent ?? this;

  const TestPlatform(this.name, this.identifier,
      {this.isDartVM: false,
      this.isBrowser: false,
      this.isJS: false,
      this.isBlink: false,
      this.isHeadless: false})
      : parent = null;

  TestPlatform._child(this.name, this.identifier, this.parent)
      : isDartVM = parent.isDartVM,
        isBrowser = parent.isBrowser,
        isJS = parent.isJS,
        isBlink = parent.isBlink,
        isHeadless = parent.isHeadless;

  /// Converts a JSON-safe representation generated by [serialize] back into a
  /// [TestPlatform].
  factory TestPlatform.deserialize(Object serialized) {
    if (serialized is String) {
      return builtIn
          .firstWhere((platform) => platform.identifier == serialized);
    }

    var map = serialized as Map;
    var parent = map["parent"];
    if (parent != null) {
      // Note that the returned platform's [parent] won't necessarily be `==` to
      // a separately-deserialized parent platform. This should be fine, though,
      // since we only deserialize platforms in the remote execution context
      // where they're only used to evaluate platform selectors.
      return new TestPlatform._child(
          map["name"], map["identifier"], new TestPlatform.deserialize(parent));
    }

    return new TestPlatform(map["name"], map["identifier"],
        isDartVM: map["isDartVM"],
        isBrowser: map["isBrowser"],
        isJS: map["isJS"],
        isBlink: map["isBlink"],
        isHeadless: map["isHeadless"]);
  }

  /// Converts [this] into a JSON-safe object that can be converted back to a
  /// [TestPlatform] using [new TestPlatform.deserialize].
  Object serialize() {
    if (builtIn.contains(this)) return identifier;

    if (parent != null) {
      return {
        "name": name,
        "identifier": identifier,
        "parent": parent.serialize()
      };
    }

    return {
      "name": name,
      "identifier": identifier,
      "isDartVM": isDartVM,
      "isBrowser": isBrowser,
      "isJS": isJS,
      "isBlink": isBlink,
      "isHeadless": isHeadless
    };
  }

  /// Returns a child of [this] that counts as both this platform's identifier
  /// and the new [identifier].
  ///
  /// This may not be called on a platform that's already a child.
  TestPlatform extend(String name, String identifier) {
    if (parent == null) return new TestPlatform._child(name, identifier, this);
    throw new StateError("A child platform may not be extended.");
  }

  String toString() => name;
}
