#!/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;

  new(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";
