// 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 analyzer.src.error;

import 'dart:collection';

import 'package:analyzer/src/generated/error.dart';

/// The maximum line length when printing extracted source code when converting
/// an [AnalyzerError] to a string.
final _MAX_ERROR_LINE_LENGTH = 120;

/// A wrapper around [AnalysisError] that provides a more user-friendly string
/// representation.
class AnalyzerError implements Exception {
  final AnalysisError error;

  AnalyzerError(this.error);

  String get message => toString();

  @override
  String toString() {
    var builder = new StringBuffer();

    // Print a less friendly string representation to ensure that
    // error.source.contents is not executed, as .contents it isn't async
    String sourceName = error.source.shortName;
    sourceName ??= '<unknown source>';
    builder.write("Error in $sourceName: ${error.message}");

//    var content = error.source.contents.data;
//    var beforeError = content.substring(0, error.offset);
//    var lineNumber = "\n".allMatches(beforeError).length + 1;
//    builder.writeln("Error on line $lineNumber of ${error.source.fullName}: "
//        "${error.message}");

//    var errorLineIndex = beforeError.lastIndexOf("\n") + 1;
//    var errorEndOfLineIndex = content.indexOf("\n", error.offset);
//    if (errorEndOfLineIndex == -1) errorEndOfLineIndex = content.length;
//    var errorLine = content.substring(
//        errorLineIndex, errorEndOfLineIndex);
//    var errorColumn = error.offset - errorLineIndex;
//    var errorLength = error.length;
//
//    // Ensure that the error line we display isn't too long.
//    if (errorLine.length > _MAX_ERROR_LINE_LENGTH) {
//      var leftLength = errorColumn;
//      var rightLength = errorLine.length - leftLength;
//      if (leftLength > _MAX_ERROR_LINE_LENGTH ~/ 2 &&
//          rightLength > _MAX_ERROR_LINE_LENGTH ~/ 2) {
//        errorLine = "..." + errorLine.substring(
//            errorColumn - _MAX_ERROR_LINE_LENGTH ~/ 2 + 3,
//            errorColumn + _MAX_ERROR_LINE_LENGTH ~/ 2 - 3)
//            + "...";
//        errorColumn = _MAX_ERROR_LINE_LENGTH ~/ 2;
//      } else if (rightLength > _MAX_ERROR_LINE_LENGTH ~/ 2) {
//        errorLine = errorLine.substring(0, _MAX_ERROR_LINE_LENGTH - 3) + "...";
//      } else {
//        assert(leftLength > _MAX_ERROR_LINE_LENGTH ~/ 2);
//        errorColumn -= errorLine.length - _MAX_ERROR_LINE_LENGTH;
//        errorLine = "..." + errorLine.substring(
//            errorLine.length - _MAX_ERROR_LINE_LENGTH + 3, errorLine.length);
//      }
//      errorLength = math.min(errorLength, _MAX_ERROR_LINE_LENGTH - errorColumn);
//    }
//    builder.writeln(errorLine);
//
//    for (var i = 0; i < errorColumn; i++) builder.write(" ");
//    for (var i = 0; i < errorLength; i++) builder.write("^");
    builder.writeln();

    return builder.toString();
  }
}

/// An error class that collects multiple [AnalyzerError]s that are emitted
/// during a single analysis.
class AnalyzerErrorGroup implements Exception {
  final List<AnalyzerError> _errors;
  AnalyzerErrorGroup(Iterable<AnalyzerError> errors)
      : _errors = errors.toList();

  /// Creates an [AnalyzerErrorGroup] from a list of lower-level
  /// [AnalysisError]s.
  AnalyzerErrorGroup.fromAnalysisErrors(Iterable<AnalysisError> errors)
      : this(errors.map((e) => new AnalyzerError(e)));

  /// The errors in this collection.
  List<AnalyzerError> get errors =>
      new UnmodifiableListView<AnalyzerError>(_errors);

  String get message => toString();
  @override
  String toString() => errors.join("\n");
}
