// 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 'generated/engine.dart';
import 'generated/error.dart';
import 'generated/source_io.dart';
import '../options.dart';

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

  ErrorFormatter(this.out, this.options);

  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) {
        errors.add(error);
        errorToLine[error] = errorInfo.lineInfo;
      }
    }
    // sort errors
    errors.sort((AnalysisError error1, AnalysisError error2) {
      // severity
      int compare = error2.errorCode.errorSeverity.compareTo(error1.errorCode.errorSeverity);
      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;
    for (AnalysisError error in errors) {
      var severity = error.errorCode.errorSeverity;
      if (severity == ErrorSeverity.ERROR) {
        errorCount++;
      } else if (severity == ErrorSeverity.WARNING) {
        if (options.warningsAreFatal) {
          errorCount++;
        } else {
          if (error.errorCode.type == ErrorType.HINT) {
            hintCount++;
          } else {
            warnCount++;
          }
        }
      }
      formatError(errorToLine, error);
    }
    // print statistics
    if (!options.machineFormat) {
      var hasErrors = errorCount != 0;
      var hasWarns = warnCount != 0;
      var hasHints = hintCount != 0;
      bool hasContent = false;
      if (hasErrors) {
        out.write(errorCount);
        out.write(' ');
        out.write(pluralize("error", errorCount));
        hasContent = true;
      }
      if (hasWarns) {
        if (hasContent) {
          if (!hasHints) {
            out.write(' and ');
          } else {
            out.write(", ");
          }
        }
        out.write(warnCount);
        out.write(' ');
        out.write(pluralize("warning", warnCount));
        hasContent = true;
      }
      if (hasHints) {
        if (hasContent) {
          out.write(" and ");
        }
        out.write(hintCount);
        out.write(' ');
        out.write(pluralize("hint", hintCount));
        hasContent = true;
      }
      if (hasContent) {
        out.writeln(" found.");
      } else {
        out.writeln("No issues found");
      }
    }
  }

  void formatError(Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
    Source source = error.source;
    LineInfo_Location location = errorToLine[error].getLocation(error.offset);
    int length = error.length;
    var severity = error.errorCode.errorSeverity;
    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);
      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 = error.errorCode.errorSeverity.displayName;
      if (error.errorCode.type == ErrorType.HINT) {
        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();
  }

  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";
    }
  }
}
