// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import '../clock.dart';
import 'stopwatch.dart';
import 'utils.dart';

/// A provider for the "current time" and points relative to the current time.
///
/// This class is designed with testability in mind. The current point in time
/// (or [now()]) is defined by a function that returns a [DateTime]. By
/// supplying your own time function or using [Clock.fixed], you can control
/// exactly what time a [Clock] returns and base your test expectations on that.
///
/// Most users should use the top-level [clock] field, which provides access to
/// a default implementation of [Clock] which can be overridden using
/// [withClock].
class Clock {
  /// The function that's called to determine this clock's notion of the current
  /// time.
  final DateTime Function() _time;

  /// Creates a clock based on the given [currentTime], or on the system clock
  /// by default.
  // ignore: deprecated_member_use_from_same_package
  const Clock([DateTime Function() currentTime = systemTime])
      : _time = currentTime;

  /// Creates [Clock] that always considers the current time to be [time].
  Clock.fixed(DateTime time) : _time = (() => time);

  /// Returns current time.
  DateTime now() => _time();

  /// Returns the point in time [Duration] amount of time ago.
  DateTime agoBy(Duration duration) => now().subtract(duration);

  /// Returns the point in time [Duration] amount of time from now.
  DateTime fromNowBy(Duration duration) => now().add(duration);

  /// Returns the point in time that's given amount of time ago.
  ///
  /// The amount of time is the sum of the individual parts.
  DateTime ago(
          {int days = 0,
          int hours = 0,
          int minutes = 0,
          int seconds = 0,
          int milliseconds = 0,
          int microseconds = 0}) =>
      agoBy(Duration(
          days: days,
          hours: hours,
          minutes: minutes,
          seconds: seconds,
          milliseconds: milliseconds,
          microseconds: microseconds));

  /// Returns the point in time that's given amount of time from now.
  ///
  /// The amount of time is the sum of the individual parts.
  DateTime fromNow(
          {int days = 0,
          int hours = 0,
          int minutes = 0,
          int seconds = 0,
          int milliseconds = 0,
          int microseconds = 0}) =>
      fromNowBy(Duration(
          days: days,
          hours: hours,
          minutes: minutes,
          seconds: seconds,
          milliseconds: milliseconds,
          microseconds: microseconds));

  /// Return the point in time [microseconds] ago.
  DateTime microsAgo(int microseconds) => ago(microseconds: microseconds);

  /// Return the point in time [microseconds] from now.
  DateTime microsFromNow(int microseconds) =>
      fromNow(microseconds: microseconds);

  /// Return the point in time [milliseconds] ago.
  DateTime millisAgo(int milliseconds) => ago(milliseconds: milliseconds);

  /// Return the point in time [milliseconds] from now.
  DateTime millisFromNow(int milliseconds) =>
      fromNow(milliseconds: milliseconds);

  /// Return the point in time [seconds] ago.
  DateTime secondsAgo(int seconds) => ago(seconds: seconds);

  /// Return the point in time [seconds] from now.
  DateTime secondsFromNow(int seconds) => fromNow(seconds: seconds);

  /// Return the point in time [minutes] ago.
  DateTime minutesAgo(int minutes) => ago(minutes: minutes);

  /// Return the point in time [minutes] from now.
  DateTime minutesFromNow(int minutes) => fromNow(minutes: minutes);

  /// Return the point in time [hours] ago.
  DateTime hoursAgo(int hours) => ago(hours: hours);

  /// Return the point in time [hours] from now.
  DateTime hoursFromNow(int hours) => fromNow(hours: hours);

  /// Return the point in time [days] ago.
  DateTime daysAgo(int days) => ago(days: days);

  /// Return the point in time [days] from now.
  DateTime daysFromNow(int days) => fromNow(days: days);

  /// Return the point in time [weeks] ago.
  DateTime weeksAgo(int weeks) => ago(days: 7 * weeks);

  /// Return the point in time [weeks] from now.
  DateTime weeksFromNow(int weeks) => fromNow(days: 7 * weeks);

  /// Return the point in time [months] ago on the same date.
  ///
  /// If the current day of the month isn't valid in the new month, the nearest
  /// valid day in the new month will be used.
  DateTime monthsAgo(int months) {
    var time = now();
    var month = (time.month - months - 1) % 12 + 1;
    var year = time.year - (months + 12 - time.month) ~/ 12;
    var day = clampDayOfMonth(year: year, month: month, day: time.day);
    return DateTime(year, month, day, time.hour, time.minute, time.second,
        time.millisecond, time.microsecond);
  }

  /// Return the point in time [months] from now on the same date.
  ///
  /// If the current day of the month isn't valid in the new month, the nearest
  /// valid day in the new month will be used.
  DateTime monthsFromNow(int months) {
    var time = now();
    var month = (time.month + months - 1) % 12 + 1;
    var year = time.year + (months + time.month - 1) ~/ 12;
    var day = clampDayOfMonth(year: year, month: month, day: time.day);
    return DateTime(year, month, day, time.hour, time.minute, time.second,
        time.millisecond, time.microsecond);
  }

  /// Return the point in time [years] ago on the same date.
  ///
  /// If the current day of the month isn't valid in the new year, the nearest
  /// valid day in the original month will be used.
  DateTime yearsAgo(int years) {
    var time = now();
    var year = time.year - years;
    var day = clampDayOfMonth(year: year, month: time.month, day: time.day);
    return DateTime(year, time.month, day, time.hour, time.minute, time.second,
        time.millisecond, time.microsecond);
  }

  /// Return the point in time [years] from now on the same date.
  ///
  /// If the current day of the month isn't valid in the new year, the nearest
  /// valid day in the original month will be used.
  DateTime yearsFromNow(int years) => yearsAgo(-years);

  /// Returns a new stopwatch that uses the current time as reported by `this`.
  Stopwatch stopwatch() => ClockStopwatch(this);

  /// Returns a new stopwatch that uses the current time as reported by `this`.
  @Deprecated('Use stopwatch() instead.')
  Stopwatch getStopwatch() => stopwatch();
}
