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

part of dart.io;

class _Timer extends LinkedListEntry<_Timer> implements Timer {
  // Disables the timer.
  static const int _NO_TIMER = -1;

  // Timers are ordered by wakeup time.
  static LinkedList<_Timer> _timers = new LinkedList<_Timer>();

  static RawReceivePort _receivePort;
  static bool _handling_callbacks = false;

  Function _callback;
  int _milliSeconds;
  int _wakeupTime = 0;

  static Timer _createTimer(void callback(Timer timer),
                            int milliSeconds,
                            bool repeating) {
    _Timer timer = new _Timer._internal();
    timer._callback = callback;
    if (milliSeconds > 0) {
      // Add one because DateTime.now() is assumed to round down
      // to nearest millisecond, not up, so that time + duration is before
      // duration milliseconds from now. Using micosecond timers like
      // Stopwatch allows detecting that the timer fires early.
      timer._wakeupTime =
          new DateTime.now().millisecondsSinceEpoch + 1 + milliSeconds;
    }
    timer._milliSeconds = repeating ? milliSeconds : -1;
    timer._addTimerToList();
    if (identical(timer, _timers.first)) {
      // The new timer is the first in queue. Update event handler.
      timer._notifyEventHandler();
    }
    return timer;
  }

  factory _Timer(int milliSeconds, void callback(Timer timer)) {
    return _createTimer(callback, milliSeconds, false);
  }

  factory _Timer.periodic(int milliSeconds, void callback(Timer timer)) {
    return _createTimer(callback, milliSeconds, true);
  }

  _Timer._internal() {}

  void _clear() {
    _callback = null;
    _milliSeconds = 0;
    _wakeupTime = 0;
  }

  bool get _repeating => _milliSeconds >= 0;

  bool get isActive => _callback != null;

  // Cancels a set timer. The timer is removed from the timer list and if
  // the given timer is the earliest timer the native timer is reset.
  void cancel() {
    _clear();
    // Return if already canceled.
    if (list == null) return;
    assert(!_timers.isEmpty);
    _Timer first = _timers.first;
    unlink();
    if (identical(first, this)) {
      _notifyEventHandler();
    }
  }

  void _advanceWakeupTime() {
    assert(_milliSeconds >= 0);
    _wakeupTime += _milliSeconds;
  }

  // Adds a timer to the timer list. Timers with the same wakeup time are
  // enqueued in order and notified in FIFO order.
  void _addTimerToList() {
    _Timer entry = _timers.isEmpty ? null : _timers.first;
    // If timer is last, add to end.
    if (entry == null || _timers.last._wakeupTime <= _wakeupTime) {
      _timers.add(this);
      return;
    }
    // Otherwise scan through and find the right position.
    while (entry != null) {
      if (_wakeupTime < entry._wakeupTime) {
        entry.insertBefore(this);
        return;
      }
      entry = entry.next;
    }
    _timers.add(this);
  }


  void _notifyEventHandler() {
    if (_handling_callbacks) {
      // While we are already handling callbacks we will not notify the event
      // handler. _handleTimeout will call _notifyEventHandler once all pending
      // timers are processed.
      return;
    }

    if (_timers.isEmpty) {
      // No pending timers: Close the receive port and let the event handler
      // know.
      if (_receivePort != null) {
        _EventHandler._sendData(null, _receivePort, _NO_TIMER);
        _shutdownTimerHandler();
      }
    } else {
      if (_receivePort == null) {
        // Create a receive port and register a message handler for the timer
        // events.
        _createTimerHandler();
      }
      _EventHandler._sendData(null,
                              _receivePort,
                              _timers.first._wakeupTime);
    }
  }


  // Creates a receive port and registers the timer handler on that
  // receive port.
  void _createTimerHandler() {

    void _handleTimeout() {
      int currentTime = new DateTime.now().millisecondsSinceEpoch;

      // Collect all pending timers.
      var pending_timers = new List();
      while (!_timers.isEmpty) {
        _Timer entry = _timers.first;
        if (entry._wakeupTime <= currentTime) {
          entry.unlink();
          pending_timers.add(entry);
        } else {
          break;
        }
      }

      // Trigger all of the pending timers. New timers added as part of the
      // callbacks will be enqueued now and notified in the next spin at the
      // earliest.
      _handling_callbacks = true;
      try {
        for (var timer in pending_timers) {
          // One of the timers in the pending_timers list can cancel
          // one of the later timers which will set the callback to
          // null.
          if (timer._callback != null) {
            var callback = timer._callback;
            if (!timer._repeating) {
              //Mark timer as inactive.
              timer._callback = null;
            }
            callback(timer);
            // Re-insert repeating timer if not canceled.
            if (timer._repeating && timer._callback != null) {
              timer._advanceWakeupTime();
              timer._addTimerToList();
            }
          }
        }
      } finally {
        _handling_callbacks = false;
        _notifyEventHandler();
      }
    }

    if(_receivePort == null) {
      _receivePort = new RawReceivePort((_) { _handleTimeout(); });
    }
  }

  void _shutdownTimerHandler() {
    _receivePort.close();
    _receivePort = null;
  }
}

// Provide a closure which will allocate a Timer object to be able to hook
// up the Timer interface in dart:isolate with the implementation here.
_getTimerFactoryClosure() {
  return (int milliSeconds, void callback(Timer timer), bool repeating) {
    if (repeating) {
      return new _Timer.periodic(milliSeconds, callback);
    }
    return new _Timer(milliSeconds, callback);
  };
}


