// 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 implements Timer {
  // Set jitter to wake up timer events that would happen in _TIMER_JITTER ms.
  static const int _TIMER_JITTER = 0;

  // Disables the timer.
  static const int _NO_TIMER = -1;

  static Timer _createTimer(void callback(Timer timer),
                           int milliSeconds,
                           bool repeating) {
    _EventHandler._start();
    if (_timers == null) {
      _timers = new DoubleLinkedQueue<_Timer>();
    }
    _Timer timer = new _Timer._internal();
    timer._callback = callback;
    timer._milliSeconds = milliSeconds;
    timer._wakeupTime = (new DateTime.now()).millisecondsSinceEpoch + milliSeconds;
    timer._repeating = repeating;
    timer._addTimerToList();
    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;
    _repeating = false;
  }


  // 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();
    DoubleLinkedQueueEntry<_Timer> entry = _timers.firstEntry();
    DoubleLinkedQueueEntry<_Timer> first = _timers.firstEntry();

     while (entry != null) {
      if (identical(entry.element, this)) {
        entry.remove();
        if (first.element == this) {
          entry = _timers.firstEntry();
          _notifyEventHandler();
        }
        return;
      }
      entry = entry.nextEntry();
    }
  }

  void _advanceWakeupTime() {
    _wakeupTime += _milliSeconds;
  }

  // Adds a timer to the timer list and resets the native timer if it is the
  // earliest timer in the list.  Timers with the same wakeup time are enqueued
  // in order and notified in FIFO order.
  void _addTimerToList() {
    if (_callback != null) {

      DoubleLinkedQueueEntry<_Timer> entry = _timers.firstEntry();
      while (entry != null) {
        if (_wakeupTime < entry.element._wakeupTime) {
          entry.prepend(this);
          return;
        }
        entry = entry.nextEntry();
      }
      _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.firstEntry() == null) {
      // 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.firstEntry().element._wakeupTime);
    }
  }


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

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

      // Collect all pending timers.
      DoubleLinkedQueueEntry<_Timer> entry = _timers.firstEntry();
      var pending_timers = new List();
      while (entry != null) {
        _Timer timer = entry.element;
        if (timer._wakeupTime <= currentTime) {
          entry.remove();
          pending_timers.add(timer);
          entry = _timers.firstEntry();
        } 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) {
            timer._callback(timer);
            if (timer._repeating) {
              timer._advanceWakeupTime();
              timer._addTimerToList();
            }
          }
        }
      } finally {
        _handling_callbacks = false;
        _notifyEventHandler();
      }
    }

    if(_receivePort == null) {
      _receivePort = new ReceivePort();
      _receivePort.receive((var message, ignored) {
        _handleTimeout();
      });
    }
  }

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


  // Timers are ordered by wakeup time.
  static DoubleLinkedQueue<_Timer> _timers;

  static ReceivePort _receivePort;
  static bool _handling_callbacks = false;

  var _callback;
  int _milliSeconds;
  int _wakeupTime;
  bool _repeating;
}

// 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);
  };
}


