// 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 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<Object>> waitUnordered<T>(Iterable<Future<T>> futures,
      {void cleanUp(T successResult)}) {
    Completer<List<Object>> completer;
    int count = 0;
    int errors = 0;
    int values = 0;
    // Initialized to `new List(count)` when count is known.
    // Filled up with values on the left, errors on the right.
    // Order is not preserved.
    List<Object> 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 = (T 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 (var 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<Object>> wait<T>(Iterable<Future<T>> futures,
      {void cleanUp(T successResult)}) {
    Completer<List<Object>> completer;
    int count = 0;
    bool hasError = false;
    int completed = 0;
    // Initialized to `new List(count)` when count is known.
    // Filled with values until the first error, then cleared
    // and filled with errors.
    List<Object> results;
    void checkDone() {
      completed++;
      if (completed < count) return;
      if (!hasError) {
        completer.complete(results);
        return;
      }
      completer.completeError(new MultiError(results));
    }

    for (var 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 = new List<Object>(count);
          hasError = true;
        }
        results[i] = e;
        checkDone();
      });
    }
    if (count == 0) return new Future.value(new List(0));
    results = new List<T>(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();
  }
}
