// 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 error_formatter;

import 'package:analyzer/src/analyzer_impl.dart';

import '../options.dart';
import 'generated/engine.dart';
import 'generated/error.dart';
import 'generated/source_io.dart';

/// Allows any [AnalysisError].
bool _anyError(AnalysisError error) => true;

/// Returns `true` if [AnalysisError] should be printed.
typedef bool _ErrorFilter(AnalysisError error);

/**
 * Helper for formatting [AnalysisError]s.
 * The two format options are a user consumable format and a machine consumable format.
 */
class ErrorFormatter {
  final StringSink out;
  final CommandLineOptions options;
  final _ErrorFilter errorFilter;

  ErrorFormatter(this.out, this.options, [this.errorFilter = _anyError]);

  void formatError(Map<AnalysisError, LineInfo> errorToLine,
      AnalysisError error) {
    Source source = error.source;
    LineInfo_Location location = errorToLine[error].getLocation(error.offset);
    int length = error.length;
    ErrorSeverity severity =
        AnalyzerImpl.computeSeverity(error, options.enableTypeChecks);
    if (options.machineFormat) {
      if (severity == ErrorSeverity.WARNING && options.warningsAreFatal) {
        severity = ErrorSeverity.ERROR;
      }
      out.write(severity);
      out.write('|');
      out.write(error.errorCode.type);
      out.write('|');
      out.write(error.errorCode.name);
      out.write('|');
      out.write(escapePipe(source.fullName));
      out.write('|');
      out.write(location.lineNumber);
      out.write('|');
      out.write(location.columnNumber);
      out.write('|');
      out.write(length);
      out.write('|');
      out.write(escapePipe(error.message));
    } else {
      String errorType = severity.displayName;
      if (error.errorCode.type == ErrorType.HINT ||
          error.errorCode.type == ErrorType.LINT) {
        errorType = error.errorCode.type.displayName;
      }
      // [warning] 'foo' is not a... (/Users/.../tmp/foo.dart, line 1, col 2)
      out.write('[$errorType] ${error.message} ');
      out.write('(${source.fullName}');
      out.write(', line ${location.lineNumber}, col ${location.columnNumber})');
    }
    out.writeln();
  }

  void formatErrors(List<AnalysisErrorInfo> errorInfos) {
    var errors = new List<AnalysisError>();
    var errorToLine = new Map<AnalysisError, LineInfo>();
    for (AnalysisErrorInfo errorInfo in errorInfos) {
      for (AnalysisError error in errorInfo.errors) {
        if (errorFilter(error)) {
          errors.add(error);
          errorToLine[error] = errorInfo.lineInfo;
        }
      }
    }
    // sort errors
    errors.sort((AnalysisError error1, AnalysisError error2) {
      // severity
      ErrorSeverity severity1 =
          AnalyzerImpl.computeSeverity(error1, options.enableTypeChecks);
      ErrorSeverity severity2 =
          AnalyzerImpl.computeSeverity(error2, options.enableTypeChecks);
      int compare = severity2.compareTo(severity1);
      if (compare != 0) {
        return compare;
      }
      // path
      compare = Comparable.compare(
          error1.source.fullName.toLowerCase(),
          error2.source.fullName.toLowerCase());
      if (compare != 0) {
        return compare;
      }
      // offset
      return error1.offset - error2.offset;
    });
    // format errors
    int errorCount = 0;
    int warnCount = 0;
    int hintCount = 0;
    int lintCount = 0;
    for (AnalysisError error in errors) {
      ErrorSeverity severity =
          AnalyzerImpl.computeSeverity(error, options.enableTypeChecks);
      if (severity == ErrorSeverity.ERROR) {
        errorCount++;
      } else if (severity == ErrorSeverity.WARNING) {
        if (options.warningsAreFatal) {
          errorCount++;
        } else {
          if (error.errorCode.type == ErrorType.HINT) {
            hintCount++;
          } else {
            warnCount++;
          }
        }
      } else if (error.errorCode.type == ErrorType.LINT) {
        lintCount++;
      }
      formatError(errorToLine, error);
    }
    // print statistics
    if (!options.machineFormat) {
      var hasErrors = errorCount != 0;
      var hasWarns = warnCount != 0;
      var hasHints = hintCount != 0;
      var hasLints = lintCount != 0;
      bool hasContent = false;
      if (hasErrors) {
        out.write(errorCount);
        out.write(' ');
        out.write(pluralize("error", errorCount));
        hasContent = true;
      }
      if (hasWarns) {
        if (hasContent) {
          if (!hasHints && !hasLints) {
            out.write(' and ');
          } else {
            out.write(", ");
          }
        }
        out.write(warnCount);
        out.write(' ');
        out.write(pluralize("warning", warnCount));
        hasContent = true;
      }
      if (hasHints) {
        if (hasContent) {
          if (!hasLints) {
            out.write(' and ');
          } else {
            out.write(", ");
          }
        }
        out.write(hintCount);
        out.write(' ');
        out.write(pluralize("hint", hintCount));
        hasContent = true;
      }
      if (hasLints) {
        if (hasContent) {
          out.write(" and ");
        }
        out.write(lintCount);
        out.write(' ');
        out.write(pluralize("lint", lintCount));
        hasContent = true;
      }
      if (hasContent) {
        out.writeln(" found.");
      } else {
        out.writeln("No issues found");
      }
    }
  }

  static String escapePipe(String input) {
    var result = new StringBuffer();
    for (var c in input.codeUnits) {
      if (c == '\\' || c == '|') {
        result.write('\\');
      }
      result.writeCharCode(c);
    }
    return result.toString();
  }

  static String pluralize(String word, int count) {
    if (count == 1) {
      return word;
    } else {
      return word + "s";
    }
  }
}
