// 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 'configuration/skip.dart';
import 'configuration/timeout.dart';
import 'platform_selector.dart';
import 'suite_platform.dart';
import 'util/identifier_regex.dart';
import 'util/pretty_print.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.
final 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) {
      var selector = PlatformSelector.parse(platform);
      if (metadata is Timeout || metadata is Skip) {
        result[selector] = _parsePlatformOptions(platform, [metadata]);
      } else if (metadata is List) {
        result[selector] = _parsePlatformOptions(platform, metadata);
      } else {
        throw ArgumentError('Metadata for platform "$platform" must be a '
            'Timeout, Skip, or List of those; was "$metadata".');
      }
    });
    return result;
  }

  static Metadata _parsePlatformOptions(
      String platform, List<dynamic> metadata) {
    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".');
      }
    }

    return Metadata.parse(timeout: timeout, skip: skip);
  }

  /// 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(Object? 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 [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,
      Object? /* String|Iterable<String> */ 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(Map 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 num?)?.toInt(),
        tags = Set.from(serialized['tags'] as Iterable),
        onPlatform = {
          for (var pair in serialized['onPlatform'] as List)
            PlatformSelector.parse(pair.first as String):
                Metadata.deserialize(pair.last as Map)
        },
        forTag = (serialized['forTag'] as Map).map((key, nested) => MapEntry(
            BooleanSelector.parse(key as String),
            Metadata.deserialize(nested as Map))),
        languageVersionComment =
            serialized['languageVersionComment'] as String?;

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

  /// 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 = <List<Object>>[];
    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
    };
  }
}
