// 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: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 = new RegExp(r"[^a-df-z\s]+", caseSensitive: false);

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

/// A regular expression that matches a section of whitespace.
final _whitespace = new 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 [new Timeout], that
/// can be overridden entirely; with [new Timeout.factor], it can be scaled
/// relative to the default.
class Timeout {
  /// A constant indicating that a test should never time out.
  static const none = const 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 = new 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 new 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 avaialble.
      if (!scanner.scan(_untilUnit)) break;
      number = double.parse(scanner.lastMatch[0]);
    }

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

  /// Returns the number of microseconds in [number] [unit]s.
  static double _microsecondsFor(double number, String unit) {
    switch (unit) {
      case "d":
        return number * 24 * 60 * 60 * 1000000;
      case "h":
        return number * 60 * 60 * 1000000;
      case "m":
        return number * 60 * 1000000;
      case "s":
        return number * 1000000;
      case "ms":
        return number * 1000;
      case "us":
        return number;
      default:
        throw new 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 new Timeout(other.duration);
    if (duration != null) return new Timeout(duration * other.scaleFactor);
    return new 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 == null ? base * scaleFactor : duration;
  }

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

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

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