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

// TODO(lrn): This should be in package:async?
/// Helper functions for working with errors.
///
/// The [MultiError] class combines multiple errors into one object,
/// and the [MultiError.wait] function works like [Future.wait] except
/// that it returns all the errors.
library pkg.isolate.errors;

import "dart:async";

class MultiError extends Error {
  // Limits the number of lines included from each error's error message.
  // A best-effort attempt is made at keeping below this number of lines
  // in the output.
  // If there are too many errors, they will all get at least one line.
  static const int _MAX_LINES = 55;
  // Minimum number of lines in the toString for each error.
  static const int _MIN_LINES_PER_ERROR = 1;

  /// The actual errors.
  final List errors;

  /// Create a `MultiError` based on a list of errors.
  ///
  /// The errors represent errors of a number of individual operations.
  ///
  /// The list may contain `null` values, if the index of the error in the
  /// list is useful.
  MultiError(this.errors);

  /// Waits for all [futures] to complete, like [Future.wait].
  ///
  /// Where `Future.wait` only reports one error, even if multiple
  /// futures complete with errors, this function will complete
  /// with a [MultiError] if more than one future completes with an error.
  ///
  /// The order of values is not preserved (if that is needed, use
  /// [wait]).
  static Future<List> waitUnordered(Iterable<Future> futures,
                                    {cleanUp(successResult)}) {
    Completer completer;
    int count = 0;
    int errors = 0;
    int values = 0;
    // Initilized to `new List(count)` when count is known.
    // Filled up with values on the left, errors on the right.
    // Order is not preserved.
    List results;
    void checkDone() {
      if (errors + values < count) return;
      if (errors == 0) {
        completer.complete(results);
        return;
      }
      var errorList = results.sublist(results.length - errors);
      completer.completeError(new MultiError(errorList));
    };
    var handleValue = (v) {
      // If this fails because [results] is null, there is a future
      // which breaks the Future API by completing immediately when
      // calling Future.then, probably by misusing a synchronous completer.
      results[values++] = v;
      if (errors > 0 && cleanUp != null) {
        new Future.sync(() => cleanUp(v));
      }
      checkDone();
    };
    var handleError = (e, s) {
      if (errors == 0 && cleanUp != null) {
        for (int i = 0; i < values; i++) {
          var value = results[i];
          if (value != null) new Future.sync(() => cleanUp(value));
        }
      }
      results[results.length - ++errors] = e;
      checkDone();
    };
    for (Future future in futures) {
      count++;
      future.then(handleValue, onError: handleError);
    }
    if (count == 0) return new Future.value(new List(0));
    results = new List(count);
    completer = new Completer();
    return completer.future;
  }

  /// Waits for all [futures] to complete, like [Future.wait].
  ///
  /// Where `Future.wait` only reports one error, even if multiple
  /// futures complete with errors, this function will complete
  /// with a [MultiError] if more than one future completes with an error.
  ///
  /// The order of values is preserved, and if any error occurs, the
  /// [MultiError.errors] list will have errors in the corresponding slots,
  /// and `null` for non-errors.
  Future<List> wait(Iterable<Future> futures, {cleanUp(successResult)}) {
    Completer completer;
    int count = 0;
    bool hasError = false;
    int completed = 0;
    // Initalized to `new List(count)` when count is known.
    // Filled with values until the first error, then cleared
    // and filled with errors.
    List results;
    void checkDone() {
      completed++;
      if (completed < count) return;
      if (!hasError) {
        completer.complete(results);
        return;
      }
      completer.completeError(new MultiError(results));
    };
    for (Future future in futures) {
      int i = count;
      count++;
      future.then((v) {
        if (!hasError) {
          results[i] = v;
        } else if (cleanUp != null) {
          new Future.sync(() => cleanUp(v));
        }
        checkDone();
      }, onError: (e, s) {
        if (!hasError) {
          if (cleanUp != null) {
            for (int i = 0; i < results.length; i++) {
              var result = results[i];
              if (result != null) new Future.sync(() => cleanUp(result));
            }
          }
          results.fillRange(0, results.length, null);
          hasError = true;
        }
        results[i] = e;
        checkDone();
      });
    }
    if (count == 0) return new Future.value(new List(0));
    results = new List(count);
    completer = new Completer();
    return completer.future;
  }

  String toString() {
    StringBuffer buffer = new StringBuffer();
    buffer.write("Multiple Errors:\n");
    int linesPerError = _MAX_LINES ~/ errors.length;
    if (linesPerError < _MIN_LINES_PER_ERROR) {
      linesPerError = _MIN_LINES_PER_ERROR;
    }

    for (int index = 0; index < errors.length; index++) {
      var error = errors[index];
      if (error == null) continue;
      String errorString = error.toString();
      int end = 0;
      for (int i = 0; i < linesPerError; i++) {
        end = errorString.indexOf('\n', end) + 1;
        if (end == 0) {
          end = errorString.length;
          break;
        }
      }
      buffer.write("#$index: ");
      buffer.write(errorString.substring(0, end));
      if (end < errorString.length) {
        buffer.write("...\n");
      }
    }
    return buffer.toString();
  }
}
