// 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:collection/collection.dart';

import '../scaffolding/skip.dart';
import '../scaffolding/timeout.dart';
import '../util/pretty_print.dart';
import '../utils.dart';
import 'platform_selector.dart';
import 'suite_platform.dart';

/// Metadata for a test or test suite.
///
/// This metadata comes from declarations on the test itself; it doesn't include
/// configuration from the user.
class Metadata {
  /// Empty metadata with only default values.
  ///
  /// Using this is slightly more efficient than manually constructing a new
  /// metadata with no arguments.
  static final empty = Metadata._();

  /// The selector indicating which platforms the suite supports.
  final PlatformSelector testOn;

  /// The modification to the timeout for the test or suite.
  final Timeout timeout;

  /// Whether the test or suite should be skipped.
  bool get skip => _skip ?? false;
  final bool? _skip;

  /// The reason the test or suite should be skipped, if given.
  final String? skipReason;

  /// Whether to use verbose stack traces.
  bool get verboseTrace => _verboseTrace ?? false;
  final bool? _verboseTrace;

  /// Whether to chain stack traces.
  bool get chainStackTraces => _chainStackTraces ?? _verboseTrace ?? false;
  final bool? _chainStackTraces;

  /// The user-defined tags attached to the test or suite.
  final Set<String> tags;

  /// The number of times to re-run a test before being marked as a failure.
  int get retry => _retry ?? 0;
  final int? _retry;

  /// Platform-specific metadata.
  ///
  /// Each key identifies a platform, and its value identifies the specific
  /// metadata for that platform. These can be applied by calling [forPlatform].
  final Map<PlatformSelector, Metadata> onPlatform;

  /// Metadata that applies only when specific tags are applied.
  ///
  /// Tag-specific metadata is applied when merging this with other metadata.
  /// Note that unlike [onPlatform], the base metadata takes precedence over any
  /// tag-specific metadata.
  ///
  /// This is guaranteed not to have any keys that match [tags]; those are
  /// resolved when the metadata is constructed.
  final Map<BooleanSelector, Metadata> forTag;

  /// The language version comment, if one is present.
  ///
  /// Only available for test suites and not individual tests.
  final String? languageVersionComment;

  /// Parses a user-provided map into the value for [onPlatform].
  static Map<PlatformSelector, Metadata> _parseOnPlatform(
      Map<String, dynamic>? onPlatform) {
    if (onPlatform == null) return {};

    var result = <PlatformSelector, Metadata>{};
    onPlatform.forEach((platform, metadata) {
      if (metadata is Timeout || metadata is Skip) {
        metadata = [metadata];
      } else if (metadata is! List) {
        throw ArgumentError('Metadata for platform "$platform" must be a '
            'Timeout, Skip, or List of those; was "$metadata".');
      }

      var selector = PlatformSelector.parse(platform);

      Timeout? timeout;
      dynamic skip;
      for (var metadatum in metadata) {
        if (metadatum is Timeout) {
          if (timeout != null) {
            throw ArgumentError('Only a single Timeout may be declared for '
                '"$platform".');
          }

          timeout = metadatum;
        } else if (metadatum is Skip) {
          if (skip != null) {
            throw ArgumentError('Only a single Skip may be declared for '
                '"$platform".');
          }

          skip = metadatum.reason ?? true;
        } else {
          throw ArgumentError('Metadata for platform "$platform" must be a '
              'Timeout, Skip, or List of those; was "$metadata".');
        }
      }

      result[selector] = Metadata.parse(timeout: timeout, skip: skip);
    });
    return result;
  }

  /// Parses a user-provided [String] or [Iterable] into the value for [tags].
  ///
  /// Throws an [ArgumentError] if [tags] is not a [String] or an [Iterable].
  static Set<String> _parseTags(tags) {
    if (tags == null) return {};
    if (tags is String) return {tags};
    if (tags is! Iterable) {
      throw ArgumentError.value(
          tags, 'tags', 'must be either a String or an Iterable.');
    }

    if (tags.any((tag) => tag is! String)) {
      throw ArgumentError.value(tags, 'tags', 'must contain only Strings.');
    }

    return Set.from(tags);
  }

  /// Creates new Metadata.
  ///
  /// [testOn] defaults to [PlatformSelector.all].
  ///
  /// If [forTag] contains metadata that applies to [tags], that metadata is
  /// included inline in the returned value. The values directly passed to the
  /// constructor take precedence over tag-specific metadata.
  factory Metadata(
      {PlatformSelector? testOn,
      Timeout? timeout,
      bool? skip,
      bool? verboseTrace,
      bool? chainStackTraces,
      int? retry,
      String? skipReason,
      Iterable<String>? tags,
      Map<PlatformSelector, Metadata>? onPlatform,
      Map<BooleanSelector, Metadata>? forTag,
      String? languageVersionComment}) {
    // Returns metadata without forTag resolved at all.
    Metadata _unresolved() => Metadata._(
        testOn: testOn,
        timeout: timeout,
        skip: skip,
        verboseTrace: verboseTrace,
        chainStackTraces: chainStackTraces,
        retry: retry,
        skipReason: skipReason,
        tags: tags,
        onPlatform: onPlatform,
        forTag: forTag,
        languageVersionComment: languageVersionComment);

    // If there's no tag-specific metadata, or if none of it applies, just
    // return the metadata as-is.
    if (forTag == null || tags == null) return _unresolved();
    tags = Set.from(tags);
    forTag = Map.from(forTag);

    // Otherwise, resolve the tag-specific components. Doing this eagerly means
    // we only have to resolve suite- or group-level tags once, rather than
    // doing it for every test individually.
    var empty = Metadata._();
    var merged = forTag.keys.toList().fold(empty, (Metadata merged, selector) {
      if (!selector.evaluate(tags!.contains)) return merged;
      return merged.merge(forTag!.remove(selector)!);
    });

    if (merged == empty) return _unresolved();
    return merged.merge(_unresolved());
  }

  /// Creates new Metadata.
  ///
  /// Unlike [new Metadata], this assumes [forTag] is already resolved.
  Metadata._({
    PlatformSelector? testOn,
    Timeout? timeout,
    bool? skip,
    this.skipReason,
    bool? verboseTrace,
    bool? chainStackTraces,
    int? retry,
    Iterable<String>? tags,
    Map<PlatformSelector, Metadata>? onPlatform,
    Map<BooleanSelector, Metadata>? forTag,
    this.languageVersionComment,
  })  : testOn = testOn ?? PlatformSelector.all,
        timeout = timeout ?? const Timeout.factor(1),
        _skip = skip,
        _verboseTrace = verboseTrace,
        _chainStackTraces = chainStackTraces,
        _retry = retry,
        tags = UnmodifiableSetView(tags == null ? {} : tags.toSet()),
        onPlatform =
            onPlatform == null ? const {} : UnmodifiableMapView(onPlatform),
        forTag = forTag == null ? const {} : UnmodifiableMapView(forTag) {
    if (retry != null) RangeError.checkNotNegative(retry, 'retry');
    _validateTags();
  }

  /// Creates a new Metadata, but with fields parsed from caller-friendly values
  /// where applicable.
  ///
  /// Throws a [FormatException] if any field is invalid.
  Metadata.parse(
      {String? testOn,
      Timeout? timeout,
      dynamic skip,
      bool? verboseTrace,
      bool? chainStackTraces,
      int? retry,
      Map<String, dynamic>? onPlatform,
      tags,
      this.languageVersionComment})
      : testOn = testOn == null
            ? PlatformSelector.all
            : PlatformSelector.parse(testOn),
        timeout = timeout ?? const Timeout.factor(1),
        _skip = skip == null ? null : skip != false,
        _verboseTrace = verboseTrace,
        _chainStackTraces = chainStackTraces,
        _retry = retry,
        skipReason = skip is String ? skip : null,
        onPlatform = _parseOnPlatform(onPlatform),
        tags = _parseTags(tags),
        forTag = const {} {
    if (skip != null && skip is! String && skip is! bool) {
      throw ArgumentError('"skip" must be a String or a bool, was "$skip".');
    }

    if (retry != null) RangeError.checkNotNegative(retry, 'retry');

    _validateTags();
  }

  /// Deserializes the result of [Metadata.serialize] into a new [Metadata].
  Metadata.deserialize(serialized)
      : testOn = serialized['testOn'] == null
            ? PlatformSelector.all
            : PlatformSelector.parse(serialized['testOn'] as String),
        timeout = _deserializeTimeout(serialized['timeout']),
        _skip = serialized['skip'] as bool?,
        skipReason = serialized['skipReason'] as String?,
        _verboseTrace = serialized['verboseTrace'] as bool?,
        _chainStackTraces = serialized['chainStackTraces'] as bool?,
        _retry = serialized['retry'] as int?,
        tags = Set.from(serialized['tags'] as Iterable),
        onPlatform = {
          for (var pair in serialized['onPlatform'])
            PlatformSelector.parse(pair.first as String):
                Metadata.deserialize(pair.last)
        },
        forTag = (serialized['forTag'] as Map).map((key, nested) => MapEntry(
            BooleanSelector.parse(key as String),
            Metadata.deserialize(nested))),
        languageVersionComment =
            serialized['languageVersionComment'] as String?;

  /// Deserializes timeout from the format returned by [_serializeTimeout].
  static Timeout _deserializeTimeout(serialized) {
    if (serialized == 'none') return Timeout.none;
    var scaleFactor = serialized['scaleFactor'];
    if (scaleFactor != null) return Timeout.factor(scaleFactor as num);
    return Timeout(Duration(microseconds: serialized['duration'] as int));
  }

  /// Throws an [ArgumentError] if any tags in [tags] aren't hyphenated
  /// identifiers.
  void _validateTags() {
    var invalidTags = tags
        .where((tag) => !tag.contains(anchoredHyphenatedIdentifier))
        .map((tag) => '"$tag"')
        .toList();

    if (invalidTags.isEmpty) return;

    throw ArgumentError("Invalid ${pluralize('tag', invalidTags.length)} "
        '${toSentence(invalidTags)}. Tags must be (optionally hyphenated) '
        'Dart identifiers.');
  }

  /// Throws a [FormatException] if any [PlatformSelector]s use 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 validatePlatformSelectors(Set<String> validVariables) {
    testOn.validate(validVariables);
    onPlatform.forEach((selector, metadata) {
      selector.validate(validVariables);
      metadata.validatePlatformSelectors(validVariables);
    });
  }

  /// Return a new [Metadata] that merges [this] with [other].
  ///
  /// If the two [Metadata]s have conflicting properties, [other] wins. If
  /// either has a [forTag] metadata for one of the other's tags, that metadata
  /// is merged as well.
  Metadata merge(Metadata other) => Metadata(
      testOn: testOn.intersection(other.testOn),
      timeout: timeout.merge(other.timeout),
      skip: other._skip ?? _skip,
      skipReason: other.skipReason ?? skipReason,
      verboseTrace: other._verboseTrace ?? _verboseTrace,
      chainStackTraces: other._chainStackTraces ?? _chainStackTraces,
      retry: other._retry ?? _retry,
      tags: tags.union(other.tags),
      onPlatform: mergeMaps(onPlatform, other.onPlatform,
          value: (metadata1, metadata2) => metadata1.merge(metadata2)),
      forTag: mergeMaps(forTag, other.forTag,
          value: (metadata1, metadata2) => metadata1.merge(metadata2)),
      languageVersionComment:
          other.languageVersionComment ?? languageVersionComment);

  /// Returns a copy of [this] with the given fields changed.
  Metadata change(
      {PlatformSelector? testOn,
      Timeout? timeout,
      bool? skip,
      bool? verboseTrace,
      bool? chainStackTraces,
      int? retry,
      String? skipReason,
      Map<PlatformSelector, Metadata>? onPlatform,
      Set<String>? tags,
      Map<BooleanSelector, Metadata>? forTag,
      String? languageVersionComment}) {
    testOn ??= this.testOn;
    timeout ??= this.timeout;
    skip ??= _skip;
    verboseTrace ??= _verboseTrace;
    chainStackTraces ??= _chainStackTraces;
    retry ??= _retry;
    skipReason ??= this.skipReason;
    onPlatform ??= this.onPlatform;
    tags ??= this.tags;
    forTag ??= this.forTag;
    languageVersionComment ??= this.languageVersionComment;
    return Metadata(
        testOn: testOn,
        timeout: timeout,
        skip: skip,
        verboseTrace: verboseTrace,
        chainStackTraces: chainStackTraces,
        skipReason: skipReason,
        onPlatform: onPlatform,
        tags: tags,
        forTag: forTag,
        retry: retry,
        languageVersionComment: languageVersionComment);
  }

  /// Returns a copy of [this] with all platform-specific metadata from
  /// [onPlatform] resolved.
  Metadata forPlatform(SuitePlatform platform) {
    if (onPlatform.isEmpty) return this;

    var metadata = this;
    onPlatform.forEach((platformSelector, platformMetadata) {
      if (!platformSelector.evaluate(platform)) return;
      metadata = metadata.merge(platformMetadata);
    });
    return metadata.change(onPlatform: {});
  }

  /// Serializes [this] into a JSON-safe object that can be deserialized using
  /// [Metadata.deserialize].
  Map<String, dynamic> serialize() {
    // Make this a list to guarantee that the order is preserved.
    var serializedOnPlatform = [];
    onPlatform.forEach((key, value) {
      serializedOnPlatform.add([key.toString(), value.serialize()]);
    });

    return {
      'testOn': testOn == PlatformSelector.all ? null : testOn.toString(),
      'timeout': _serializeTimeout(timeout),
      'skip': _skip,
      'skipReason': skipReason,
      'verboseTrace': _verboseTrace,
      'chainStackTraces': _chainStackTraces,
      'retry': _retry,
      'tags': tags.toList(),
      'onPlatform': serializedOnPlatform,
      'forTag': forTag.map((selector, metadata) =>
          MapEntry(selector.toString(), metadata.serialize())),
      'languageVersionComment': languageVersionComment,
    };
  }

  /// Serializes timeout into a JSON-safe object.
  dynamic _serializeTimeout(Timeout timeout) {
    if (timeout == Timeout.none) return 'none';
    return {
      'duration': timeout.duration?.inMicroseconds,
      'scaleFactor': timeout.scaleFactor
    };
  }
}
