// 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:meta/meta_meta.dart';
import 'package:string_scanner/string_scanner.dart';

/// A regular expression that matches text until a letter or whitespace.
///
/// This is intended to scan through a number without actually encoding the full
/// Dart number grammar. It doesn't stop on "e" because that can be a component
/// of numbers.
final _untilUnit = RegExp(r'[^a-df-z\s]+', caseSensitive: false);

/// A regular expression that matches a time unit.
final _unit = RegExp(r'([um]s|[dhms])', caseSensitive: false);

/// A regular expression that matches a section of whitespace.
final _whitespace = RegExp(r'\s+');

/// A class representing a modification to the default timeout for a test.
///
/// By default, a test will time out after 30 seconds. With [Timeout], that
/// can be overridden entirely; with [Timeout.factor], it can be scaled
/// relative to the default.
@Target({TargetKind.library})
final class Timeout {
  /// A constant indicating that a test should never time out.
  static const none = Timeout._none();

  /// The timeout duration.
  ///
  /// If set, this overrides the default duration entirely. It's `null` for
  /// timeouts with a non-null [scaleFactor] and for [Timeout.none].
  final Duration? duration;

  /// The timeout factor.
  ///
  /// The default timeout will be multiplied by this to get the new timeout.
  /// Thus a factor of 2 means that the test will take twice as long to time
  /// out, and a factor of 0.5 means that it will time out twice as quickly.
  ///
  /// This is `null` for timeouts with a non-null [duration] and for
  /// [Timeout.none].
  final num? scaleFactor;

  /// Declares an absolute timeout that overrides the default.
  const Timeout(this.duration) : scaleFactor = null;

  /// Declares a relative timeout that scales the default.
  const Timeout.factor(this.scaleFactor) : duration = null;

  const Timeout._none()
      : scaleFactor = null,
        duration = null;

  /// Parse the timeout from a user-provided string.
  ///
  /// This supports the following formats:
  ///
  /// * `Number "x"`, which produces a relative timeout with the given scale
  ///   factor.
  ///
  /// * `(Number ("d" | "h" | "m" | "s" | "ms" | "us") (" ")?)+`, which produces
  ///   an absolute timeout with the duration given by the sum of the given
  ///   units.
  ///
  /// * `"none"`, which produces [Timeout.none].
  ///
  /// Throws a [FormatException] if [timeout] is not in a valid format
  factory Timeout.parse(String timeout) {
    var scanner = StringScanner(timeout);

    // First check for the string "none".
    if (scanner.scan('none')) {
      scanner.expectDone();
      return Timeout.none;
    }

    // Scan a number. This will be either a time unit or a scale factor.
    scanner.expect(_untilUnit, name: 'number');
    var number = double.parse(scanner.lastMatch![0]!);

    // A number followed by "x" is a scale factor.
    if (scanner.scan('x') || scanner.scan('X')) {
      scanner.expectDone();
      return Timeout.factor(number);
    }

    // Parse time units until none are left. The condition is in the middle of
    // the loop because we've already parsed the first number.
    var microseconds = 0.0;
    while (true) {
      scanner.expect(_unit, name: 'unit');
      microseconds += _microsecondsFor(number, scanner.lastMatch![0]!);

      scanner.scan(_whitespace);

      // Scan the next number, if it's available.
      if (!scanner.scan(_untilUnit)) break;
      number = double.parse(scanner.lastMatch![0]!);
    }

    scanner.expectDone();
    return Timeout(Duration(microseconds: microseconds.round()));
  }

  /// Returns the number of microseconds in [number] [unit]s.
  static double _microsecondsFor(double number, String unit) => switch (unit) {
        'd' => number * 24 * 60 * 60 * 1000000,
        'h' => number * 60 * 60 * 1000000,
        'm' => number * 60 * 1000000,
        's' => number * 1000000,
        'ms' => number * 1000,
        'us' => number,
        _ => throw ArgumentError('Unknown unit $unit.'),
      };

  /// Returns a new [Timeout] that merges [this] with [other].
  ///
  /// [Timeout.none] takes precedence over everything. If timeout is
  /// [Timeout.none] and [other] declares a [duration], that takes precedence.
  /// Otherwise, this timeout's [duration] or [factor] are multiplied by
  /// [other]'s [factor].
  Timeout merge(Timeout other) {
    if (this == none || other == none) return none;
    if (other.duration != null) return Timeout(other.duration);
    if (duration != null) return Timeout(duration! * other.scaleFactor!);
    return Timeout.factor(scaleFactor! * other.scaleFactor!);
  }

  /// Returns a new [Duration] from applying [this] to [base].
  ///
  /// If this is [none], returns `null`.
  Duration? apply(Duration base) {
    if (this == none) return null;
    return duration ?? base * scaleFactor!;
  }

  @override
  int get hashCode => duration.hashCode ^ 5 * scaleFactor.hashCode;

  @override
  bool operator ==(Object other) =>
      other is Timeout &&
      other.duration == duration &&
      other.scaleFactor == scaleFactor;

  @override
  String toString() {
    if (duration != null) return duration.toString();
    if (scaleFactor != null) return '${scaleFactor}x';
    return 'none';
  }
}
