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

library services.scheduler;

import 'dart:async';
import 'dart:collection';

class TaskScheduler {
  final Queue<_Task<dynamic>> _taskQueue = Queue<_Task<dynamic>>();
  bool _isActive = false;

  int get queueCount => _taskQueue.length;

  Future<T> _performTask<T>(Task<T> task) {
    if (task.timeoutDuration != null) {
      return task.perform().timeout(task.timeoutDuration);
    } else {
      return task.perform();
    }
  }

  Future<T> schedule<T>(Task<T> task) {
    if (!_isActive) {
      _isActive = true;
      return _performTask(task).whenComplete(_next);
    }
    Completer<T> taskResult = Completer<T>();
    _taskQueue.add(_Task<T>(task, taskResult));
    return taskResult.future;
  }

  void _next() {
    assert(_isActive);
    if (_taskQueue.isEmpty) {
      _isActive = false;
      return;
    }
    _Task<dynamic> first = _taskQueue.removeFirst();
    first.taskResult.complete(_performTask(first.task).whenComplete(_next));
  }
}

// Internal unit of scheduling.
class _Task<T> {
  final Task<T> task;
  final Completer<T> taskResult;
  _Task(this.task, this.taskResult);
}

// Public working data structure.
abstract class Task<T> {
  Future<T> perform();
  Duration timeoutDuration;
}

class ClosureTask<T> extends Task<T> {
  Future<T> Function() _closure;

  ClosureTask(this._closure, {Duration timeoutDuration}) {
    this.timeoutDuration = timeoutDuration;
  }

  @override
  Future<T> perform() {
    return _closure();
  }
}
