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