// Copyright (c) 2012, 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 csslib.src.messages;

import 'package:logging/logging.dart' show Level;
import 'package:source_span/source_span.dart';

import 'options.dart';

// TODO(terry): Remove the global messages, use some object that tracks
//              compilation state.

/// The global [Messages] for tracking info/warnings/messages.
Messages messages;

// Color constants used for generating messages.
final String GREEN_COLOR = '\u001b[32m';
final String RED_COLOR = '\u001b[31m';
final String MAGENTA_COLOR = '\u001b[35m';
final String NO_COLOR = '\u001b[0m';

/// Map between error levels and their display color.
final Map<Level, String> _ERROR_COLORS = (() {
  var colorsMap = Map<Level, String>();
  colorsMap[Level.SEVERE] = RED_COLOR;
  colorsMap[Level.WARNING] = MAGENTA_COLOR;
  colorsMap[Level.INFO] = GREEN_COLOR;
  return colorsMap;
})();

/// Map between error levels and their friendly name.
final Map<Level, String> _ERROR_LABEL = (() {
  var labels = Map<Level, String>();
  labels[Level.SEVERE] = 'error';
  labels[Level.WARNING] = 'warning';
  labels[Level.INFO] = 'info';
  return labels;
})();

/// A single message from the compiler.
class Message {
  final Level level;
  final String message;
  final SourceSpan span;
  final bool useColors;

  Message(this.level, this.message, {SourceSpan span, bool useColors = false})
      : this.span = span,
        this.useColors = useColors;

  String toString() {
    var output = StringBuffer();
    bool colors = useColors && _ERROR_COLORS.containsKey(level);
    var levelColor = colors ? _ERROR_COLORS[level] : null;
    if (colors) output.write(levelColor);
    output..write(_ERROR_LABEL[level])..write(' ');
    if (colors) output.write(NO_COLOR);

    if (span == null) {
      output.write(message);
    } else {
      output.write('on ');
      output.write(span.message(message, color: levelColor));
    }

    return output.toString();
  }
}

typedef PrintHandler = void Function(Message obj);

/// This class tracks and prints information, warnings, and errors emitted by
/// the compiler.
class Messages {
  /// Called on every error. Set to blank function to supress printing.
  final PrintHandler printHandler;

  final PreprocessorOptions options;

  final List<Message> messages = <Message>[];

  Messages({PreprocessorOptions options, this.printHandler = print})
      : options = options != null ? options : PreprocessorOptions();

  /// Report a compile-time CSS error.
  void error(String message, SourceSpan span) {
    var msg = Message(Level.SEVERE, message,
        span: span, useColors: options.useColors);

    messages.add(msg);

    printHandler(msg);
  }

  /// Report a compile-time CSS warning.
  void warning(String message, SourceSpan span) {
    if (options.warningsAsErrors) {
      error(message, span);
    } else {
      var msg = Message(Level.WARNING, message,
          span: span, useColors: options.useColors);

      messages.add(msg);
    }
  }

  /// Report and informational message about what the compiler is doing.
  void info(String message, SourceSpan span) {
    var msg =
        Message(Level.INFO, message, span: span, useColors: options.useColors);

    messages.add(msg);

    if (options.verbose) printHandler(msg);
  }

  /// Merge [newMessages] to this message lsit.
  void mergeMessages(Messages newMessages) {
    messages.addAll(newMessages.messages);
    newMessages.messages
        .where((message) => message.level == Level.SEVERE || options.verbose)
        .forEach(printHandler);
  }
}
