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

library task;

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

import 'package:stack_trace/stack_trace.dart';

import 'future_group.dart';
import 'schedule.dart';
import 'utils.dart';

typedef Future TaskBody();

/// A single task to be run as part of a [TaskQueue].
///
/// There are two levels of tasks. **Top-level tasks** are created by calling
/// [TaskQueue.schedule] before the queue in question is running. They're run in
/// sequence as part of that [TaskQueue]. **Nested tasks** are created by
/// calling [TaskQueue.schedule] once the queue is already running, and are run
/// in parallel as part of a top-level task.
class Task {
  /// The queue to which this [Task] belongs.
  final TaskQueue queue;

  /// Child tasks that have been spawned while running this task. This will be
  /// empty if this task is a nested task.
  List<Task> get children => new UnmodifiableListView(_children);
  final _children = new Queue<Task>();

  /// A [FutureGroup] that will complete once all current child tasks are
  /// finished running. This will be null if no child tasks are currently
  /// running.
  FutureGroup _childGroup;

  /// A description of this task. Used for debugging. May be `null`.
  final String description;

  /// The parent task, if this is a nested task that was started while another
  /// task was running. This will be `null` for top-level tasks.
  final Task parent;

  /// The body of the task.
  TaskBody fn;

  /// The current state of [this].
  TaskState get state => _state;
  var _state = TaskState.WAITING;

  /// The identifier of the task. For top-level tasks, this is the index of the
  /// task within [queue]; for nested tasks, this is the index within
  /// [parent.children]. It's used for debugging when [description] isn't
  /// provided.
  int _id;

  /// A Future that will complete to the return value of [fn] once this task
  /// finishes running.
  Future get result => _resultCompleter.future;
  final _resultCompleter = new Completer();

  final Trace stackTrace;

  Task(fn(), String description, TaskQueue queue)
    : this._(fn, description, queue, null, queue.contents.length);

  Task._child(fn(), String description, Task parent)
    : this._(fn, description, parent.queue, parent, parent.children.length);

  Task._(fn(), this.description, TaskQueue queue, this.parent, this._id)
      : queue = queue,
        stackTrace = new Trace.current() {
    this.fn = () {
      if (state != TaskState.WAITING) {
        throw new StateError("Can't run $state task '$this'.");
      }

      _state = TaskState.RUNNING;
      var future = new Future.value().then((_) => fn())
          .whenComplete(() {
        if (_childGroup == null || _childGroup.completed) return null;
        return _childGroup.future;
      });
      chainToCompleter(future, _resultCompleter);
      return future;
    };

    // If the parent queue experiences an error before this task has started
    // running, pipe that error out through [result]. This ensures that we don't
    // get deadlocked by something like `expect(schedule(...), completes)`.
    queue.onTasksComplete.catchError((e) {
      if (state == TaskState.WAITING) _resultCompleter.completeError(e);
    });

    // catchError makes sure any error thrown by fn isn't top-leveled by virtue
    // of being passed to the result future.
    result.then((_) {
      _state = TaskState.SUCCESS;
    }).catchError((e) {
      _state = TaskState.ERROR;
      throw e;
    }).catchError((_) {});
  }

  /// Run [fn] as a child of this task. Returns a Future that will complete with
  /// the result of the child task. This task will not complete until [fn] has
  /// finished.
  Future runChild(fn(), String description) {
    var task = new Task._child(fn, description, this);
    _children.add(task);
    if (_childGroup == null || _childGroup.completed) {
      _childGroup = new FutureGroup();
    }
    // Ignore errors in the FutureGroup; they'll get picked up via wrapFuture,
    // and we don't want them to short-circuit the other Futures.
    _childGroup.add(task.result.catchError((_) {}));
    task.fn();
    return task.result;
  }

  String toString() => description == null ? "#$_id" : description;

  String toStringWithStackTrace() {
    var result = toString();
    if (stackTrace != null) {
      var stackString = prefixLines(terseTraceString(stackTrace));
      result += "\n\nStack trace:\n$stackString";
    }
    return result;
  }

  /// Returns a detailed representation of [queue] with this task highlighted.
  String generateTree() => queue.generateTree(this);
}

/// An enum of states for a [Task].
class TaskState {
  /// The task is waiting to be run.
  static const WAITING = const TaskState._("WAITING");

  /// The task is currently running.
  static const RUNNING = const TaskState._("RUNNING");

  /// The task has finished running successfully.
  static const SUCCESS = const TaskState._("SUCCESS");

  /// The task has finished running with an error.
  static const ERROR = const TaskState._("ERROR");

  /// The name of the state.
  final String name;

  /// Whether the state indicates that the task has finished running. This is
  /// true for both the [SUCCESS] and [ERROR] states.
  bool get isDone => this == SUCCESS || this == ERROR;

  const TaskState._(this.name);

  String toString() => name;
}
