// Copyright (c) 2021, 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.

// @dart = 2.9

import "package:expect/expect.dart";

// Tests that local DateTime constructor works correctly around
// time zone changes.

void main() {
  // Find two points in time with different time zones.
  // Search linearly back from 2020-01-01 in steps of 60 days.
  // Stop if reaching 1970-01-01 (epoch) without finding anything.
  var time = DateTime.utc(2020, 1, 1).millisecondsSinceEpoch;
  var offset =
      DateTime.fromMillisecondsSinceEpoch(time).timeZoneOffset.inMilliseconds;
  var time2 = time;
  var offset2 = offset;
  // Whether the first change found moved the clock forward.
  bool changeForward = false;
  // 60 days.
  const delta = 60 * Duration.millisecondsPerDay;
  while (time2 > 0) {
    time2 -= delta;
    offset2 = DateTime.fromMillisecondsSinceEpoch(time2)
        .timeZoneOffset
        .inMilliseconds;
    if (verbose) {
      print("Search: ${tz(time2, offset2)} - ${tz(time, offset)}");
    }
    if (offset2 != offset) {
      // Two different time zones found. Now find the precise (to the minute)
      // time where a change happened, and test that.
      test(findChange(time2, time));
      // Remeber if the change moved the clock forward or backward.
      changeForward = offset2 < offset;
      break;
    }
  }
  time = time2;
  // Find a change in the other direction.
  // Keep iterating backwards to find another time zone
  // where the change was in the other direction.
  while (time > 0) {
    time -= delta;
    offset =
        DateTime.fromMillisecondsSinceEpoch(time).timeZoneOffset.inMilliseconds;
    if (verbose) {
      print("Search: ${tz(time2, offset2)} - ${tz(time, offset)}");
    }
    if (offset != offset2) {
      if ((offset < offset2) != changeForward) {
        test(findChange(time, time2));
        break;
      } else {
        // Another change in the same direction.
        // Probably rare, but move use this time
        // as end-point instead, so the binary search will be shorter.
        time2 = time;
        offset2 = offset;
      }
    }
  }
}

/// Tests that a local time zone change is correctly represented
/// by local time [DateTime] objects created from date-time values.
void test(TimeZoneChange change) {
  if (verbose) print("Test of $change");
  // Sanity check. The time zones match the [change] one second
  // before and after the change.
  var before = DateTime.fromMillisecondsSinceEpoch(
      change.msSinceEpoch - Duration.millisecondsPerSecond);
  Expect.equals(change.msOffsetBefore, before.timeZoneOffset.inMilliseconds);
  var after = DateTime.fromMillisecondsSinceEpoch(
      change.msSinceEpoch + Duration.millisecondsPerSecond);
  Expect.equals(change.msOffsetAfter, after.timeZoneOffset.inMilliseconds);

  if (verbose) print("From MS    : ${dtz(before)} --- ${dtz(after)}");

  // Create local DateTime objects for the same YMDHMS as the
  // values above. See that we pick the correct local time for them.

  // One second before the change, even if clock moves backwards,
  // we pick a value that is in the earlier time zone.
  var localBefore = DateTime(before.year, before.month, before.day, before.hour,
      before.minute, before.second);
  Expect.equals(before, localBefore);

  // Asking for a calendar date one second after the change.
  var localAfter = DateTime(after.year, after.month, after.day, after.hour,
      after.minute, after.second);
  if (verbose) print("From YMDHMS: ${dtz(localBefore)} --- ${dtz(localAfter)}");
  if (before.timeZoneOffset < after.timeZoneOffset) {
    // Clock moved forwards.
    // We're asking for a clock time which doesn't exist.
    if (verbose) {
      print("Forward: ${dtz(after)} vs ${dtz(localAfter)}");
    }
    Expect.equals(after, localAfter);
  } else {
    // Clock moved backwards.
    // We're asking for a clock time which exists more than once.
    // Should be in the former time zone.
    Expect.equals(before.timeZoneOffset, localAfter.timeZoneOffset);
  }
}

/// Finds a time zone change between [before] and [after].
///
/// The [before] time must be before [after],
/// and the local time zone at the two points must be different.
///
/// Finds the point in time, with one minute precision,
/// where the time zone changed, and returns this point,
/// as well as the time zone offset before and after the change.
TimeZoneChange findChange(int before, int after) {
  var min = Duration.millisecondsPerMinute;
  assert(before % min == 0);
  assert(after % min == 0);
  var offsetBefore =
      DateTime.fromMillisecondsSinceEpoch(before).timeZoneOffset.inMilliseconds;
  var offsetAfter =
      DateTime.fromMillisecondsSinceEpoch(after).timeZoneOffset.inMilliseconds;
  // Binary search for the precise (to 1 minute increments)
  // time where the change happened.
  while (after - before > min) {
    var mid = before + (after - before) ~/ 2;
    mid -= mid % min;
    var offsetMid =
        DateTime.fromMillisecondsSinceEpoch(mid).timeZoneOffset.inMilliseconds;
    if (verbose) {
      print(
          "Bsearch: ${tz(before, offsetBefore)} - ${tz(mid, offsetMid)} - ${tz(after, offsetAfter)}");
    }
    if (offsetMid == offsetBefore) {
      before = mid;
    } else if (offsetMid == offsetAfter) {
      after = mid;
    } else {
      // Third timezone in the middle. Probably rare.
      // Use that as either before or after.
      // Keep the direction of the time zone change.
      var forwardChange = offsetAfter > offsetBefore;
      if ((offsetMid > offsetBefore) == forwardChange) {
        after = mid;
        offsetAfter = offsetMid;
      } else {
        before = mid;
        offsetBefore = offsetMid;
      }
    }
  }
  return TimeZoneChange(after, offsetBefore, offsetAfter);
}

/// A local time zone change.
class TimeZoneChange {
  /// The point in time where the clocks were adjusted.
  final int msSinceEpoch;

  /// The time zone offset before the change.
  final int msOffsetBefore;

  /// The time zone offset since the change.
  final int msOffsetAfter;
  TimeZoneChange(this.msSinceEpoch, this.msOffsetBefore, this.msOffsetAfter);
  String toString() {
    var local = DateTime.fromMillisecondsSinceEpoch(msSinceEpoch);
    var offsetBefore = Duration(milliseconds: msOffsetBefore);
    var offsetAfter = Duration(milliseconds: msOffsetAfter);
    return "$local (${ltz(offsetBefore)} -> ${ltz(offsetAfter)})";
  }
}

// Helpers when printing timezones.

/// Point in time in ms since epoch, and known offset in ms.
String tz(int ms, int offset) => "${DateTime.fromMillisecondsSinceEpoch(ms)}"
    "${ltz(Duration(milliseconds: offset))}";

/// Time plus Zone from DateTime
String dtz(DateTime dt) => "$dt${dt.isUtc ? "" : ltz(dt.timeZoneOffset)}";

/// Time zone from duration ("+h:ss" format).
String ltz(Duration d) => "${d.isNegative ? "-" : "+"}${d.inHours}"
    ":${(d.inMinutes % 60).toString().padLeft(2, "0")}";

/// Set to true if debugging.
const bool verbose = false;
