#!/usr/bin/env dart
// Copyright (c) 2017, 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.

import 'package:kernel/kernel.dart';
import 'package:kernel/naive_type_checker.dart';
import 'package:kernel/text/ast_to_text.dart';

class ErrorFormatter implements FailureListener {
  List<String> failures = <String>[];
  int get numberOfFailures => failures.length;

  @override
  void reportNotAssignable(TreeNode where, DartType from, DartType to) {
    reportFailure(
        where,
        '${ansiBlue}${from}${ansiReset} ${ansiYellow}is not assignable to'
        '${ansiReset} ${ansiBlue}${to}${ansiReset}');
  }

  @override
  void reportInvalidOverride(
      Member ownMember, Member superMember, String message) {
    reportFailure(ownMember, '''
Incompatible override of ${superMember} with ${ownMember}:

    ${_realign(message, '    ')}''');
  }

  @override
  void reportFailure(TreeNode where, String message) {
    final dynamic context = where is Class || where is Library
        ? where
        : _findEnclosingMember(where);
    String sourceLocation = '<unknown source>';
    String? sourceLine = null;

    // Try finding original source line.
    final int fileOffset = _findFileOffset(where);
    if (fileOffset != TreeNode.noOffset) {
      final Uri fileUri = _fileUriOf(context);

      final Component component = context.enclosingComponent;
      final Source source = component.uriToSource[fileUri]!;
      final Location location = component.getLocation(fileUri, fileOffset)!;
      final List<int> lineStarts = source.lineStarts!;
      final int lineStart = lineStarts[location.line - 1];
      final int lineEnd = (location.line < lineStarts.length)
          ? lineStarts[location.line]
          : (source.source.length - 1);
      if (lineStart < source.source.length &&
          lineEnd < source.source.length &&
          lineStart < lineEnd) {
        sourceLocation = '${fileUri}:${location.line}';
        sourceLine = new String.fromCharCodes(
            source.source.getRange(lineStart, lineEnd));
      }
    }

    // Find the name of the enclosing member.
    String name = "";
    dynamic body = context;
    if (context is Class || context is Library) {
      name = context.name;
    } else if (context is Procedure || context is Constructor) {
      final dynamic parent = context.parent;
      final String? parentName =
          parent is Class ? parent.name : (parent as Library).name;
      name = "${parentName}::${context.name.text}";
    } else {
      final Field field = context as Field;
      if (where is Field) {
        name = "${field.parent}.${field.name}";
      } else {
        name = "field initializer for ${field.parent}.${field.name}";
      }
    }

    String failure = '''
-----------------------------------------------------------------------
In ${name} at ${sourceLocation}:

    ${message.replaceAll('\n', '\n    ')}

Kernel:
|
|   ${_realign(HighlightingPrinter.stringifyContainingLines(body, where))}
|
''';

    if (sourceLine != null) {
      failure = '''$failure
Source:
|
|   ${_realign(sourceLine)}
|
''';
    }
    failures.add(failure);
  }

  static Uri _fileUriOf(FileUriNode node) {
    return node.fileUri;
  }

  static String _realign(String str, [String prefix = '|   ']) =>
      str.trimRight().replaceAll('\n', '\n${prefix}');

  static int _findFileOffset(TreeNode? context) {
    while (context != null && context.fileOffset == TreeNode.noOffset) {
      context = context.parent;
    }

    return context?.fileOffset ?? TreeNode.noOffset;
  }

  static Member _findEnclosingMember(TreeNode n) {
    TreeNode? context = n;
    while (context is! Member) {
      context = context!.parent;
    }
    return context;
  }
}

/// Extension of a [Printer] that highlights the given node using ANSI
/// escape sequences.
class HighlightingPrinter extends Printer {
  final Node highlight;

  HighlightingPrinter(this.highlight)
      : super(new StringBuffer(), syntheticNames: globalDebuggingNames);

  @override
  bool shouldHighlight(Node node) => highlight == node;

  static const String kHighlightStart = ansiRed;
  static const String kHighlightEnd = ansiReset;

  @override
  void startHighlight(Node node) {
    sink.write(kHighlightStart);
  }

  @override
  void endHighlight(Node node) {
    sink.write(kHighlightEnd);
  }

  /// Stringify the given [node] but only return lines that contain string
  /// representation of the [highlight] node.
  static String stringifyContainingLines(Node node, Node highlight) {
    if (node == highlight) {
      final String firstLine = debugNodeToString(node).split('\n').first;
      return "${kHighlightStart}${firstLine}${kHighlightEnd}";
    }

    final HighlightingPrinter p = new HighlightingPrinter(highlight);
    p.writeNode(node);
    final String text = p.sink.toString();
    return _onlyHighlightedLines(text).join('\n');
  }

  static Iterable<String> _onlyHighlightedLines(String text) sync* {
    for (String line
        in text.split('\n').skipWhile((l) => !l.contains(kHighlightStart))) {
      yield line;
      if (line.contains(kHighlightEnd)) {
        break;
      }
    }
  }
}

const String ansiBlue = "\u001b[1;34m";
const String ansiYellow = "\u001b[1;33m";
const String ansiRed = "\u001b[1;31m";
const String ansiReset = "\u001b[0;0m";
