// 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.

// Timer heap implemented as a array-based binary heap[0].
// This allows for O(1) `first`, O(log(n)) `remove`/`removeFirst` and O(log(n))
// `add`.
//
// To ensure the timers are ordered by insertion time, the _Timer class has a
// `_id` field set when added to the heap.
//
// [0] http://en.wikipedia.org/wiki/Binary_heap
class _TimerHeap {
  List<_Timer> _list;
  int _used = 0;

  _TimerHeap([int initSize = 7])
      : _list = new List<_Timer>(initSize);

  bool get isEmpty => _used == 0;

  _Timer get first => _list[0];

  bool isFirst(_Timer timer) => timer._indexOrNext == 0;

  void add(_Timer timer) {
    if (_used == _list.length) {
      _resize();
    }
    timer._indexOrNext = _used++;
    _list[timer._indexOrNext] = timer;
    _bubbleUp(timer);
  }

  _Timer removeFirst() {
    var f = first;
    remove(f);
    return f;
  }

  void remove(_Timer timer) {
    _used--;
    if (isEmpty) {
      _list[0] = null;
      timer._indexOrNext = null;
      return;
    }
    var last = _list[_used];
    if (!identical(last, timer)) {
      last._indexOrNext = timer._indexOrNext;
      _list[last._indexOrNext] = last;
      if (last._compareTo(timer) < 0) {
        _bubbleUp(last);
      } else {
        _bubbleDown(last);
      }
    }
    _list[_used] = null;
    timer._indexOrNext = null;
  }

  void _resize() {
    var newList = new List(_list.length * 2 + 1);
    newList.setRange(0, _used, _list);
    _list = newList;
  }

  void _bubbleUp(_Timer timer) {
    while (!isFirst(timer)) {
      Timer parent = _parent(timer);
      if (timer._compareTo(parent) < 0) {
        _swap(timer, parent);
      } else {
        break;
      }
    }
  }

  void _bubbleDown(_Timer timer) {
    while (true) {
      int leftIndex = _leftChildIndex(timer._indexOrNext);
      int rightIndex = _rightChildIndex(timer._indexOrNext);
      _Timer newest = timer;
      if (leftIndex < _used && _list[leftIndex]._compareTo(newest) < 0) {
        newest = _list[leftIndex];
      }
      if (rightIndex < _used && _list[rightIndex]._compareTo(newest) < 0) {
        newest = _list[rightIndex];
      }
      if (identical(newest, timer)) {
        // We are where we should be, break.
        break;
      }
      _swap(newest, timer);
    }
  }

  void _swap(_Timer first, _Timer second) {
    int tmp = first._indexOrNext;
    first._indexOrNext = second._indexOrNext;
    second._indexOrNext = tmp;
    _list[first._indexOrNext] = first;
    _list[second._indexOrNext] = second;
  }

  Timer _parent(_Timer timer) => _list[_parentIndex(timer._indexOrNext)];
  Timer _leftChild(_Timer timer) => _list[_leftChildIndex(timer._indexOrNext)];
  Timer _rightChild(_Timer timer) =>
      _list[_rightChildIndex(timer._indexOrNext)];

  static int _parentIndex(int index) => (index - 1) ~/ 2;
  static int _leftChildIndex(int index) => 2 * index + 1;
  static int _rightChildIndex(int index) => 2 * index + 2;
}

class _Timer implements Timer {
  // Cancels the timer in the event handler.
  static const int _NO_TIMER = -1;

  // Timers are ordered by wakeup time.
  static _TimerHeap _heap = new _TimerHeap();
  static _Timer _firstZeroTimer;
  static _Timer _lastZeroTimer;

  // We use an id to be able to sort timers with the same expiration time.
  // ids are recycled after ID_MASK enqueues or when the timer queue is empty.
  static int _ID_MASK = 0x1fffffff;
  static int _idCount = 0;

  static RawReceivePort _receivePort;
  static SendPort _sendPort;
  static int _scheduledWakeupTime;
  // Keep track whether at least one message is pending in the event loop. This
  // way we do not have to notify for every pending _firstZeroTimer.
  static var _messagePending = false;

  static bool _handlingCallbacks = false;

  Function _callback;  // Closure to call when timer fires. null if canceled.
  int _wakeupTime;  // Expiration time.
  int _milliSeconds;  // Duration specified at creation.
  bool _repeating;  // Indicates periodic timers.
  var _indexOrNext;  // Index if part of the TimerHeap, link otherwise.
  int _id;  // Incrementing id to enable sorting of timers with same expiry.

  // Get the next available id. We accept collisions and reordering when the
  // _idCount overflows and the timers expire at the same millisecond.
  static int _nextId() {
    var result = _idCount;
    _idCount = (_idCount + 1) & _ID_MASK;
    return result;
  }

  _Timer._internal(this._callback,
                   this._wakeupTime,
                   this._milliSeconds,
                   this._repeating) : _id = _nextId();

  static Timer _createTimer(void callback(Timer timer),
                            int milliSeconds,
                            bool repeating) {
    // Negative timeouts are treated as if 0 timeout.
    if (milliSeconds < 0) {
      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 microsecond timers like
    // Stopwatch allows detecting that the timer fires early.
    int now = new DateTime.now().millisecondsSinceEpoch;
    int wakeupTime = (milliSeconds == 0) ? now : (now + 1 + milliSeconds);

    _Timer timer = new _Timer._internal(callback,
                                        wakeupTime,
                                        milliSeconds,
                                        repeating);

    if (timer._addTimerToHeap()) {
      // The new timer is the first in queue. Update event handler.
      _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);
  }

  bool get _isInHeap => _indexOrNext is int;

  void _clear() {
    _callback = null;
  }

  int _compareTo(_Timer other) {
    int c = _wakeupTime - other._wakeupTime;
    if (c != 0) return c;
    return _id - other._id;
  }

  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 event handler is notified.
  void cancel() {
    _clear();
    if (!_isInHeap) return;
    // Only heap timers are really removed. Others are just dropped on
    // notification.
    bool update = (_firstZeroTimer == null) && _heap.isFirst(this);
    _heap.remove(this);
    if (update) {
      _notifyEventHandler();
    }
  }

  void _advanceWakeupTime() {
    // Recalculate the next wakeup time. For repeating timers with a 0 timeout
    // the next wakeup time is now.
    _id = _nextId();
    if (_milliSeconds > 0) {
      _wakeupTime += _milliSeconds;
    } else {
      _wakeupTime = new DateTime.now().millisecondsSinceEpoch;
    }
  }

  // Adds a timer to the heap or timer list. Timers with the same wakeup time
  // are enqueued in order and notified in FIFO order.
  bool _addTimerToHeap() {
    if (_milliSeconds == 0) {
      if (_firstZeroTimer == null) {
        _lastZeroTimer = this;
        _firstZeroTimer = this;
        return true;
      } else {
        _lastZeroTimer._indexOrNext = this;
        _lastZeroTimer = this;
        return false;
      }
    } else {
      _heap.add(this);
      return _firstZeroTimer == null && _heap.isFirst(this);
    }
  }


  static void _notifyEventHandler() {
    if (_handlingCallbacks) {
      // 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 ((_firstZeroTimer == null) && _heap.isEmpty) {
      // No pending timers: Close the receive port and let the event handler
      // know.
      if (_receivePort != null) {
        VMLibraryHooks.eventHandlerSendData(null, _sendPort, _NO_TIMER);
        _shutdownTimerHandler();
      }
    } else {
      if (_receivePort == null) {
        // Create a receive port and register a message handler for the timer
        // events.
        _createTimerHandler();
      }
      if (_firstZeroTimer != null) {
        if (!_messagePending) {
          _sendPort.send(null);
          _messagePending = true;  // Reset when the port receives a message.
        }
      } else {
        var wakeupTime = _heap.first._wakeupTime;
        if ((_scheduledWakeupTime == null) ||
            (wakeupTime != _scheduledWakeupTime)) {
          VMLibraryHooks.eventHandlerSendData(null, _sendPort, wakeupTime);
          _scheduledWakeupTime = wakeupTime;
        }
      }
    }
  }

  static void _handleTimeout() {
    // Fast exit if no timers have been scheduled.
    if (_heap.isEmpty && (_firstZeroTimer == null)) {
      assert(_receivePort == null);
      return;
    }

    // Collect all pending timers.
    var head = null;
    var tail = null;
    if (_heap.isEmpty) {
      // Only immediate timers are scheduled. Take over the whole list as is.
      assert(_firstZeroTimer != null);
      assert(_lastZeroTimer != null);
      head = _firstZeroTimer;
      tail = _lastZeroTimer;
      _firstZeroTimer = null;
      _lastZeroTimer = null;
    } else {
      assert(!_heap.isEmpty);
      // Keep track of the lowest wakeup times for both the list and heap. If
      // the respective queue is empty move its time beyond the current time.
      var currentTime = new DateTime.now().millisecondsSinceEpoch;
      var heapTime = _heap.first._wakeupTime;
      var listTime = (_firstZeroTimer == null) ?
          (currentTime + 1) : _firstZeroTimer._wakeupTime;

      while ((heapTime <= currentTime) || (listTime <= currentTime)) {
        var timer;
        // Consume the timers in order by removing from heap or list based on
        // their wakeup time and update the queue's time.
        assert((heapTime != listTime) ||
               ((_heap.first != null) && (_firstZeroTimer != null)));
        if ((heapTime < listTime) ||
            ((heapTime == listTime) &&
             (_heap.first._id < _firstZeroTimer._id))) {
          timer = _heap.removeFirst();
          heapTime = _heap.isEmpty ?
              (currentTime + 1) : _heap.first._wakeupTime;
        } else {
          timer = _firstZeroTimer;
          assert(timer._milliSeconds == 0);
          _firstZeroTimer = timer._indexOrNext;
          if (_firstZeroTimer == null) {
            _lastZeroTimer = null;
            listTime = currentTime + 1;
          } else {
            // We want to drain all entries from the list as they should have
            // been pending for 0 ms. To prevent issues with current time moving
            // we ensure that the listTime does not go beyond current, unless
            // the list is empty.
            listTime = _firstZeroTimer._wakeupTime;
            if (listTime > currentTime) {
              listTime = currentTime;
            }
          }
        }

        // Append this timer to the pending timer list.
        timer._indexOrNext = null;
        if (head == null) {
          assert(tail == null);
          head = timer;
          tail = timer;
        } else {
          tail._indexOrNext = timer;
          tail = timer;
        }
      }
    }

    // No timers queued: Early exit.
    if (head == null) {
      return;
    }

    // If there are no pending timers currently reset the id space before we
    // have a chance to enqueue new timers.
    assert(_firstZeroTimer == null);
    if (_heap.isEmpty) {
      _idCount = 0;
    }

    // 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.
    _handlingCallbacks = true;
    try {
      while (head != null) {
        // Dequeue the first candidate timer.
        var timer = head;
        head = timer._indexOrNext;
        timer._indexOrNext = null;

        // 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._addTimerToHeap();
          }
          // Execute pending micro tasks.
          _runPendingImmediateCallback();
        }
      }
    } finally {
      _handlingCallbacks = false;
      _notifyEventHandler();
    }
  }

  // Creates a receive port and registers an empty handler on that port. Just
  // the triggering of the event loop will ensure that timers are executed.
  static _ignoreMessage(_) {
    _messagePending = false;
  }

  static void _createTimerHandler() {
    assert(_receivePort == null);
    _receivePort = new RawReceivePort(_ignoreMessage);
    _sendPort = _receivePort.sendPort;
    _scheduledWakeupTime = null;
    _messagePending = false;
  }

  static void _shutdownTimerHandler() {
    _receivePort.close();
    _receivePort = null;
    _sendPort = null;
    _scheduledWakeupTime = null;
    _messagePending = false;
  }

  // The Timer factory registered with the dart:async library by the embedder.
  static Timer _factory(int milliSeconds,
                        void callback(Timer timer),
                        bool repeating) {
    if (repeating) {
      return new _Timer.periodic(milliSeconds, callback);
    }
    return new _Timer(milliSeconds, callback);
  }
}

_setupHooks() {
  VMLibraryHooks.timerFactory = _Timer._factory;
}
