// 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.

import 'package:boolean_selector/boolean_selector.dart';
import 'package:source_span/source_span.dart';

import 'operating_system.dart';
import 'runtime.dart';
import 'suite_platform.dart';

/// The set of variable names that are valid for all platform selectors.
final _universalValidVariables = {
  'posix',
  'dart-vm',
  'browser',
  'js',
  'blink',
  'google'
}
  ..addAll(Runtime.builtIn.map((r) => r.identifier))
  ..addAll(OperatingSystem.all.map((os) => os.identifier));

/// An expression for selecting certain platforms, including operating systems
/// and browsers.
///
/// This uses the [boolean selector][] syntax.
///
/// [boolean selector]: https://pub.dev/packages/boolean_selector
class PlatformSelector {
  /// A selector that declares that a test can be run on all platforms.
  static const all = PlatformSelector._(BooleanSelector.all);

  /// The boolean selector used to implement this selector.
  final BooleanSelector _inner;

  /// The source span from which this selector was parsed.
  final SourceSpan _span;

  /// Parses [selector].
  ///
  /// If [span] is passed, it indicates the location of the text for [selector]
  /// in a larger document. It's used for error reporting.
  PlatformSelector.parse(String selector, [SourceSpan span])
      : _inner =
            _wrapFormatException(() => BooleanSelector.parse(selector), span),
        _span = span;

  const PlatformSelector._(this._inner) : _span = null;

  /// Runs [body] and wraps any [FormatException] it throws in a
  /// [SourceSpanFormatException] using [span].
  ///
  /// If [span] is `null`, runs [body] as-is.
  static T _wrapFormatException<T>(T Function() body, SourceSpan span) {
    if (span == null) return body();

    try {
      return body();
    } on FormatException catch (error) {
      throw SourceSpanFormatException(error.message, span);
    }
  }

  /// Throws a [FormatException] if this selector uses any variables that don't
  /// appear either in [validVariables] or in the set of variables that are
  /// known to be valid for all selectors.
  void validate(Set<String> validVariables) {
    if (identical(this, all)) return;

    _wrapFormatException(
        () => _inner.validate((name) =>
            _universalValidVariables.contains(name) ||
            validVariables.contains(name)),
        _span);
  }

  /// Returns whether the selector matches the given [platform].
  ///
  /// [os] defaults to [OperatingSystem.none].
  bool evaluate(SuitePlatform platform) {
    return _inner.evaluate((String variable) {
      if (variable == platform.runtime.identifier) return true;
      if (variable == platform.runtime.parent?.identifier) return true;
      if (variable == platform.os.identifier) return true;
      switch (variable) {
        case 'dart-vm':
          return platform.runtime.isDartVM;
        case 'browser':
          return platform.runtime.isBrowser;
        case 'js':
          return platform.runtime.isJS;
        case 'blink':
          return platform.runtime.isBlink;
        case 'posix':
          return platform.os.isPosix;
        case 'google':
          return platform.inGoogle;
        default:
          return false;
      }
    });
  }

  /// Returns a new [PlatformSelector] that matches only platforms matched by
  /// both [this] and [other].
  PlatformSelector intersection(PlatformSelector other) {
    if (other == PlatformSelector.all) return this;
    return PlatformSelector._(_inner.intersection(other._inner));
  }

  @override
  String toString() => _inner.toString();

  @override
  bool operator ==(other) =>
      other is PlatformSelector && _inner == other._inner;

  @override
  int get hashCode => _inner.hashCode;
}
