// Copyright (c) 2024, 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 'dart:io';
import 'dart:typed_data';

import 'package:_fe_analyzer_shared/src/scanner/characters.dart'
    show $SPACE, $CARET;
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
import 'package:front_end/src/fasta/util/parser_ast.dart';
import 'package:front_end/src/fasta/util/parser_ast_helper.dart';
import 'package:kernel/ast.dart';
import 'package:package_config/package_config.dart';

import '../test/coverage_helper.dart';
import 'interval_list.dart';
import 'parser_ast_indexer.dart';

void main(List<String> arguments) {
  Uri? coverageUri;
  Uri? packagesUri;

  for (String argument in arguments) {
    const String coverage = "--coverage=";
    const String packages = "--packages=";
    if (argument.startsWith(coverage)) {
      coverageUri =
          Uri.base.resolveUri(Uri.file(argument.substring(coverage.length)));
    } else if (argument.startsWith(packages)) {
      packagesUri =
          Uri.base.resolveUri(Uri.file(argument.substring(packages.length)));
    } else {
      throw "Unsupported argument: $argument";
    }
  }
  if (coverageUri == null) {
    throw "Need --coverage=<dir>/ argument";
  }
  if (packagesUri == null) {
    throw "Need --packages=<path/to/package_config.json> argument";
  }

  Stopwatch stopwatch = new Stopwatch()..start();
  mergeFromDirUri(packagesUri, coverageUri, silent: false);
  print("Done in ${stopwatch.elapsed}");
}

Map<Uri, CoverageInfo>? mergeFromDirUri(
  Uri packagesUri,
  Uri coverageUri, {
  required bool silent,
}) {
  void output(Object? object) {
    if (silent) return;
    print(object);
  }

  PackageConfig packageConfig;
  try {
    packageConfig = PackageConfig.parseBytes(
        File.fromUri(packagesUri).readAsBytesSync(), packagesUri);
  } catch (e) {
    // When will we want to catch this?
    output("Error trying to read package config: $e");
    return null;
  }

  // TODO(jensj): We should allow for comments to "excuse" something from not
  // being covered. E.g. sometimes we throw after a number of if's saying
  // something like "this can probably never happen", and thus we can't expect
  // to test that.

  // TODO(jensj): We should be able to extract the "coverable" offsets from
  // source/dill, thus avoiding asking the VM to do it and basically we would
  // then be able to just ignore the uncompiled stuff from the VM. It could
  // probably also be used for speeding up doing coverage in flutter. We need to
  // be "sharp" about what the VM includes and what the VM doesn't include
  // though. I assume it doesn't include everything, but really I don't know.

  // TODO(jensj): Things that are not covered by one of our suites should
  // probably be marked specifically as we generally want tests "close".

  // Merge the data:
  //  * combine hits, and keep track of where they come from (display name)
  //  * combine misses, but remove misses that are hits
  //  * ignore not compiled regions.
  Map<Uri, Hit> hits = {};
  Map<Uri, Set<int>> misses = {};

  for (FileSystemEntity entry
      in Directory.fromUri(coverageUri).listSync(recursive: true)) {
    if (entry is! File) continue;
    try {
      Coverage coverage = Coverage.loadFromFile(entry);
      output("Loaded $entry as coverage file.");
      _mergeCoverageInto(coverage, misses, hits);
    } catch (e) {
      output("Couldn't load $entry as coverage file.");
    }
  }
  output("");

  Set<Uri> knownUris = {};
  knownUris.addAll(hits.keys);
  knownUris.addAll(misses.keys);

  int filesCount = 0;
  int allCoveredCount = 0;
  int hitsTotal = 0;
  int missesTotal = 0;
  int errorsCount = 0;

  Map<Uri, CoverageInfo> result = {};

  for (Uri uri in knownUris.toList()
    ..sort(((a, b) => a.toString().compareTo(b.toString())))) {
    // Don't care about coverage for testing stuff.
    if (uri.toString().startsWith("package:front_end/src/testing/")) continue;

    Hit? hit = hits[uri];
    Set<int>? miss = misses[uri];
    List<int> hitsSorted =
        hit == null ? const [] : (hit._data.keys.toList()..sort());

    CoverageInfo processInfo =
        process(packageConfig, uri, miss ?? const {}, hitsSorted);
    output(processInfo.visualization);
    result[uri] = processInfo;
    filesCount++;
    if (processInfo.error) {
      errorsCount++;
    } else {
      if (processInfo.allCovered) {
        allCoveredCount++;
      }
      hitsTotal += processInfo.hitCount;
      missesTotal += processInfo.missCount;
    }

    output("");
  }

  output("Processed $filesCount files with $errorsCount error(s) and "
      "$allCoveredCount files being covered 100%.");
  int percentHit = (hitsTotal * 100) ~/ (hitsTotal + missesTotal);
  output("All-in-all $hitsTotal hits and $missesTotal misses ($percentHit%).");

  return result;
}

class CoverageInfo {
  final bool error;
  final bool allCovered;
  final int missCount;
  final int hitCount;
  final String visualization;

  CoverageInfo.error(this.visualization)
      : error = true,
        allCovered = false,
        missCount = 0,
        hitCount = 0;

  CoverageInfo(
      {required this.allCovered,
      required this.missCount,
      required this.hitCount,
      required this.visualization})
      : error = false;
}

CoverageInfo process(PackageConfig packageConfig, Uri uri,
    Set<int> untrimmedMisses, List<int> hitsSorted) {
  Uri? fileUri = packageConfig.resolve(uri);
  if (fileUri == null) {
    return new CoverageInfo.error("Couldn't find file uri for $uri");
  }
  File f = new File.fromUri(fileUri);
  Uint8List rawBytes;
  try {
    rawBytes = f.readAsBytesSync();
  } catch (e) {
    return new CoverageInfo.error("Error reading file $f");
  }

  List<int> lineStarts = [];
  // TODO(jensj): "allowPatterns" for instance should use data from the package
  // config to be set correctly.
  CompilationUnitEnd ast = getAST(
    rawBytes,
    includeComments: true,
    enableExtensionMethods: true,
    enableNonNullable: true,
    enableTripleShift: true,
    lineStarts: lineStarts,
  );

  AstIndexerAndIgnoreCollector astIndexer =
      AstIndexerAndIgnoreCollector.collect(ast);

  // TODO(jensj): Extract all comments and use those as well here.
  // TODO(jensj): Should some comment throw/report and error if covered?
  // E.g. "we expect this to be dead code, if it isn't we want to know."

  StringBuffer visualization = new StringBuffer();

  IntervalList ignoredIntervals =
      astIndexer.ignoredStartEnd.buildIntervalList();
  var (:bool allCovered, :Set<int> trimmedMisses) =
      _trimIgnoredAndPrintPercentages(
          visualization, ignoredIntervals, untrimmedMisses, hitsSorted, uri);

  if (allCovered) {
    return new CoverageInfo(
        allCovered: allCovered,
        missCount: trimmedMisses.length,
        hitCount: hitsSorted.length,
        visualization: visualization.toString());
  }

  CompilationUnitBegin unitBegin = ast.children!.first as CompilationUnitBegin;
  Token firstToken = unitBegin.token;
  Source source = new Source(lineStarts, rawBytes, uri, fileUri);

  List<int> sortedMisses = trimmedMisses.toList()..sort();

  int lastLine = -1;
  int lastOffset = -1;
  Uint8List? indentation;
  String? line;
  Token token = firstToken;
  int? latestNodeIndex;
  int nextHitIndexToCheck = 0;

  void printFinishedLine() {
    if (indentation != null) {
      String? name = astIndexer.nameOfEntitySpanning(lastOffset);
      String pointer = new String.fromCharCodes(indentation!);
      if (name != null) {
        visualization.writeln("$uri:$lastLine:\nIn '$name':\n$line\n$pointer");
      } else {
        visualization.writeln("$uri:$lastLine:\n$line\n$pointer");
      }
      line = null;
      indentation = null;
    }
  }

  int nextOffsetIndex = 0;
  while (nextOffsetIndex < sortedMisses.length) {
    int offset = sortedMisses[nextOffsetIndex];
    nextOffsetIndex++;
    while (offset > token.charOffset) {
      token = token.next!;
      if (token.isEof) break;
    }

    int? thisNodeIndex = astIndexer.findNodeIndexSpanningPosition(offset);
    if (thisNodeIndex != null && thisNodeIndex != latestNodeIndex) {
      // First miss in this entity: Does it have any hits?
      latestNodeIndex = thisNodeIndex;
      printFinishedLine();
      bool foundHit = false;
      int first = astIndexer.moveNodeIndexToFirstMetadataIfAny(thisNodeIndex)!;
      int last = astIndexer.moveNodeIndexPastMetadata(
              astIndexer.findNodeIndexSpanningPosition(offset)) ??
          thisNodeIndex;
      int beginOffset = astIndexer.positionStartEndIndex[first * 2 + 0];
      int endOffset = astIndexer.positionStartEndIndex[last * 2 + 1];
      for (; nextHitIndexToCheck < hitsSorted.length; nextHitIndexToCheck++) {
        int hit = hitsSorted[nextHitIndexToCheck];
        if (hit >= beginOffset && hit <= endOffset) {
          foundHit = true;
          break;
        } else if (hit > endOffset) {
          break;
        }
      }
      if (!foundHit) {
        // Don't show a line with only metadata.
        offset = astIndexer.positionStartEndIndex[last * 2];
        Location location = source.getLocation(uri, offset);
        String line = source.getTextLine(location.line)!;
        String? name = astIndexer.nameOfEntitySpanning(offset);

        if (name != null) {
          visualization.writeln(
              "$uri:${location.line}: No coverage for '$name'.\n$line\n");
          // TODO(jensj): Squiggly line under the identifier of the entity?
        } else {
          visualization.writeln(
              "$uri:${location.line}: No coverage for entity.\n$line\n");
        }

        // Skip the rest of the miss points inside the entity.
        while (nextOffsetIndex < sortedMisses.length) {
          offset = sortedMisses[nextOffsetIndex];
          if (offset > endOffset) break;
          nextOffsetIndex++;
        }

        continue;
      }
    }

    Location location = source.getLocation(uri, offset);
    if (location.line != lastLine) {
      printFinishedLine();
      lastLine = location.line;
      line = source.getTextLine(location.line)!;
      indentation = new Uint8List(line!.length)
        ..fillRange(0, line!.length, $SPACE);
    }

    try {
      if (offset == token.charOffset) {
        for (int i = 0; i < token.length; i++) {
          indentation![location.column - 1 + i] = $CARET;
        }
      } else {
        indentation![location.column - 1] = $CARET;
      }
      lastOffset = offset;
    } catch (e) {
      visualization.writeln("Error on offset $offset --- $location: $e");
      visualization.writeln(
          "Maybe the coverage data is not up to date with the source?");
      return new CoverageInfo.error(visualization.toString());
    }
  }
  printFinishedLine();

  return new CoverageInfo(
      allCovered: allCovered,
      missCount: trimmedMisses.length,
      hitCount: hitsSorted.length,
      visualization: visualization.toString());
}

({bool allCovered, Set<int> trimmedMisses}) _trimIgnoredAndPrintPercentages(
    StringBuffer visualization,
    IntervalList ignoredIntervals,
    Set<int> untrimmedMisses,
    List<int> hitsSorted,
    Uri uri) {
  int missCount = untrimmedMisses.length;
  int hitCount = hitsSorted.length;
  Set<int> trimmedMisses;
  if (hitCount + missCount == 0) {
    visualization.writeln("$uri");
    return (allCovered: true, trimmedMisses: untrimmedMisses);
  } else {
    if (!ignoredIntervals.isEmpty) {
      trimmedMisses = {};
      for (int position in untrimmedMisses) {
        if (ignoredIntervals.contains(position)) {
          // Ignored position!
        } else {
          trimmedMisses.add(position);
        }
      }
      missCount = trimmedMisses.length;
    } else {
      trimmedMisses = untrimmedMisses;
    }

    if (missCount > 0) {
      visualization.writeln(
          "$uri: ${(hitCount / (hitCount + missCount) * 100).round()}% "
          "($missCount misses)");
      return (allCovered: false, trimmedMisses: trimmedMisses);
    } else {
      visualization.writeln("$uri: 100% (OK)");
      return (allCovered: true, trimmedMisses: trimmedMisses);
    }
  }
}

void _mergeCoverageInto(
    Coverage coverage, Map<Uri, Set<int>> misses, Map<Uri, Hit> hits) {
  for (FileCoverage fileCoverage in coverage.getAllFileCoverages()) {
    if (fileCoverage.uri.isScheme("package") &&
        fileCoverage.uri.pathSegments.first != "front_end") continue;
    if (fileCoverage.misses.isNotEmpty) {
      Set<int> miss = misses[fileCoverage.uri] ??= {};
      miss.addAll(fileCoverage.misses);
    }

    if (fileCoverage.hits.isNotEmpty) {
      Hit hit = hits[fileCoverage.uri] ??= new Hit();
      for (int fileHit in fileCoverage.hits) {
        hit.addHit(fileHit, coverage.displayName);
      }
    }
  }

  // Now remove any misses that are actually hits.
  for (MapEntry<Uri, Set<int>> entry in misses.entries) {
    Hit? hit = hits[entry.key];
    if (hit == null) continue;
    entry.value.removeAll(hit._data.keys);
  }
}

class Hit {
  Map<int, List<String>> _data = {};

  void addHit(int offset, String displayName) {
    (_data[offset] ??= []).add(displayName);
  }
}

class AstIndexerAndIgnoreCollector extends AstIndexer {
  final Set<String> topLevelMethodNamesToIgnore = {
    "debug",
    "debugString",
  };
  final Set<String> classMethodNamesToIgnore = {
    "debug",
    "debugString",
    "toString",
    "debugName",
    "writeNullabilityOn",
  };

  final IntervalListBuilder ignoredStartEnd = new IntervalListBuilder();

  late final _AstIndexerAndIgnoreCollectorBody _collectorBody =
      new _AstIndexerAndIgnoreCollectorBody(this);

  static AstIndexerAndIgnoreCollector collect(ParserAstNode ast) {
    AstIndexerAndIgnoreCollector collector =
        new AstIndexerAndIgnoreCollector._();
    ast.accept(collector);

    assert(collector.positionNodeIndex.length ==
        collector.positionNodeName.length);
    assert(collector.positionNodeIndex.length * 2 ==
        collector.positionStartEndIndex.length);

    return collector;
  }

  AstIndexerAndIgnoreCollector._() {}

  @override
  void visitTopLevelMethodEnd(TopLevelMethodEnd node) {
    super.visitTopLevelMethodEnd(node);
    String name = node.getNameIdentifier().token.lexeme;
    if (topLevelMethodNamesToIgnore.contains(name)) {
      // Ignore this method including metadata.
      assert(positionNodeIndex.last == node);
      assert(positionStartEndIndex.last == node.endToken.charEnd);
      int index = positionNodeIndex.length - 1;
      int firstIndex = moveNodeIndexToFirstMetadataIfAny(index)!;
      ignoredStartEnd.addIntervalIncludingEnd(
          positionStartEndIndex[firstIndex * 2 + 0], node.endToken.charEnd);
    } else {
      node.accept(_collectorBody);
    }
  }

  @override
  void containerMethod(BeginAndEndTokenParserAstNode node, String name) {
    super.containerMethod(node, name);
    if (classMethodNamesToIgnore.contains(name)) {
      // Ignore this class method including metadata.
      assert(positionNodeIndex.last == node);
      assert(positionStartEndIndex.last == node.endToken.charEnd);
      int index = positionNodeIndex.length - 1;
      int firstIndex = moveNodeIndexToFirstMetadataIfAny(index)!;
      ignoredStartEnd.addIntervalIncludingEnd(
          positionStartEndIndex[firstIndex * 2 + 0], node.endToken.charEnd);
    } else {
      node.accept(_collectorBody);
    }
  }
}

class _AstIndexerAndIgnoreCollectorBody extends RecursiveParserAstVisitor {
  final AstIndexerAndIgnoreCollector _collector;

  _AstIndexerAndIgnoreCollectorBody(this._collector);

  bool _recordIfIsCallToNotExpectedCoverage(
      BeginAndEndTokenParserAstNode node) {
    List<ParserAstNode>? children = node.children;
    if (children != null &&
        children.length >= 5 &&
        children[1] is IdentifierHandle) {
      IdentifierHandle identifier = children[1] as IdentifierHandle;
      if ((identifier.token.lexeme == "internalProblem" ||
              identifier.token.lexeme == "unimplemented" ||
              identifier.token.lexeme == "unhandled" ||
              identifier.token.lexeme == "unexpected" ||
              identifier.token.lexeme == "unsupported") &&
          children[2] is NoTypeArgumentsHandle &&
          children[3] is ArgumentsEnd &&
          children[4] is SendHandle) {
        // This is (probably) a call to `internalProblem`/`unimplemented`/etc
        // inside an if block --- we don't expect these to happen
        // so we'll ignore them.
        _collector.ignoredStartEnd.addIntervalIncludingEnd(
            node.beginToken.charOffset, node.endToken.charEnd);
        return true;
      }
    }
    return false;
  }

  @override
  void visitReturnStatementEnd(ReturnStatementEnd node) {
    if (_recordIfIsCallToNotExpectedCoverage(node)) return;
    super.visitReturnStatementEnd(node);
  }

  @override
  void visitBlockEnd(BlockEnd node) {
    if (_recordIfIsCallToNotExpectedCoverage(node)) return;
    super.visitBlockEnd(node);
  }
}
