// Copyright (c) 2019, 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.

// This is a hacked-together client of the NNBD migration API, intended for
// early testing of the migration process.  It runs a small hardcoded set of
// packages through the migration engine and outputs statistics about the
// result of migration, as well as categories (and counts) of exceptions that
// occurred.

import 'dart:io';

import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:args/args.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:path/path.dart' as path;

import 'src/package.dart';

void main(List<String> args) async {
  ArgResults parsedArgs = parseArguments(args)!;

  Sdk sdk = Sdk(parsedArgs['sdk'] as String);

  warnOnNoAssertions();

  Playground playground =
      Playground(defaultPlaygroundPath, parsedArgs['clean'] as bool);

  List<Package> packages = [
    for (String package in parsedArgs['packages'] as Iterable<String>)
      SdkPackage(package),
    for (String package in parsedArgs['manual_packages'] as Iterable<String>)
      ManualPackage(package),
  ];

  var packageNames = parsedArgs['git_packages'] as Iterable<String>;
  await Future.wait(packageNames.map((n) async => packages.add(
      await GitPackage.gitPackageFactory(
          n, playground, parsedArgs['update'] as bool?))));

  String? categoryOfInterest =
      parsedArgs.rest.isEmpty ? null : parsedArgs.rest.single;

  var listener = _Listener(categoryOfInterest,
      printExceptionNodeOnly: parsedArgs['exception_node_only'] as bool?);
  assert(listener.numExceptions == 0);
  var overallStartTime = DateTime.now();
  for (var package in packages) {
    print('Migrating $package');
    var startTime = DateTime.now();
    listener.currentPackage = package.name;
    var contextCollection = AnalysisContextCollectionImpl(
        includedPaths: package.migrationPaths as List<String>,
        sdkPath: sdk.sdkPath);

    var files = <String>{};
    var previousExceptionCount = listener.numExceptions;
    for (var context in contextCollection.contexts) {
      var localFiles =
          context.contextRoot.analyzedFiles().where((s) => s.endsWith('.dart'));
      files.addAll(localFiles);
      var session = context.currentSession;
      LineInfo getLineInfo(String path) =>
          (session.getFile(path) as FileResult).lineInfo;
      var migration =
          NullabilityMigration(listener, getLineInfo, permissive: true);
      for (var file in localFiles) {
        var resolvedUnit =
            await session.getResolvedUnit(file) as ResolvedUnitResult;
        if (!resolvedUnit.errors.any((e) => e.severity == Severity.error)) {
          migration.prepareInput(resolvedUnit);
        } else {
          print('  Skipping $file; it has errors.');
        }
      }
      for (var file in localFiles) {
        var resolvedUnit =
            await session.getResolvedUnit(file) as ResolvedUnitResult;
        if (!resolvedUnit.errors.any((e) => e.severity == Severity.error)) {
          migration.processInput(resolvedUnit);
        }
      }
      for (var file in localFiles) {
        var resolvedUnit =
            await session.getResolvedUnit(file) as ResolvedUnitResult;
        if (!resolvedUnit.errors.any((e) => e.severity == Severity.error)) {
          migration.finalizeInput(resolvedUnit);
        }
      }
      migration.finish();
    }

    var endTime = DateTime.now();
    print('  Migrated $package in ${endTime.difference(startTime).inSeconds} '
        'seconds');
    print('  ${files.length} files found');
    var exceptionCount = listener.numExceptions - previousExceptionCount;
    print('  $exceptionCount exceptions in this package');
  }

  var overallDuration = DateTime.now().difference(overallStartTime);
  print('${packages.length} packages migrated in ${overallDuration.inSeconds} '
      'seconds');
  print('${listener.numTypesMadeNullable} types made nullable');
  print('${listener.numNullChecksAdded} null checks added');
  print('${listener.numVariablesMarkedLate} variables marked late');
  print('${listener.numInsertedCasts} casts inserted');
  print('${listener.numInsertedParenthesis} parenthesis groupings inserted');
  print('${listener.numMetaImportsAdded} meta imports added');
  print('${listener.numRequiredAnnotationsAdded} required annotations added');
  print('${listener.numDeadCodeSegmentsFound} dead code segments found');
  print('and ${listener.numOtherEdits} other edits not categorized');
  print('${listener.numExceptions} exceptions in '
      '${listener.groupedExceptions.length} categories');

  var sortedExceptions = [
    for (var entry in listener.groupedExceptions.entries)
      ExceptionCategory(entry.key, entry.value)
  ]..sort((category1, category2) => category2.count.compareTo(category1.count));
  var exceptionalPackages =
      sortedExceptions.expand((category) => category.packageNames).toSet();
  print('Packages with exceptions: $exceptionalPackages');
  print('Exception categories:');
  for (var category in sortedExceptions) {
    print('  $category');
  }

  if (categoryOfInterest == null) {
    print('\n(Note: to show stack traces & nodes for a particular failure,'
        ' rerun with a search string as an argument.)');
  }
}

ArgResults? parseArguments(List<String> args) {
  ArgParser argParser = ArgParser();
  ArgResults? parsedArgs;

  argParser.addFlag('clean',
      abbr: 'c',
      defaultsTo: false,
      help: 'Recursively delete the playground directory before beginning.');

  argParser.addFlag('help', abbr: 'h', help: 'Display options');

  argParser.addFlag('exception_node_only',
      defaultsTo: false,
      negatable: true,
      help: 'Only print the exception node instead of the full stack trace.');

  argParser.addFlag('update',
      abbr: 'u',
      defaultsTo: false,
      negatable: true,
      help: 'Auto-update fetched packages in the playground.');

  argParser.addOption('sdk',
      abbr: 's',
      defaultsTo: path.dirname(path.dirname(Platform.resolvedExecutable)),
      help: 'Select the root of the SDK to analyze against for this run '
          '(compiled with --nnbd).  For example: ../../xcodebuild/DebugX64NNBD/dart-sdk');

  argParser.addMultiOption(
    'git_packages',
    abbr: 'g',
    defaultsTo: [],
    help: 'Shallow-clone the given git repositories into a playground area,'
        ' run pub get on them, and migrate them.',
  );

  argParser.addMultiOption(
    'manual_packages',
    abbr: 'm',
    defaultsTo: [],
    help: 'Run migration against packages in these directories.  Does not '
        'run pub get, any git commands, or any other preparation.',
  );

  argParser.addMultiOption(
    'packages',
    abbr: 'p',
    defaultsTo: [],
    help: 'The list of SDK packages to run the migration against.',
  );

  try {
    parsedArgs = argParser.parse(args);
  } on ArgParserException {
    stderr.writeln(argParser.usage);
    exit(1);
  }
  if (parsedArgs['help'] as bool) {
    print(argParser.usage);
    exit(0);
  }

  if (parsedArgs.rest.length > 1) {
    throw 'invalid args. Specify *one* argument to get exceptions of interest.';
  }
  return parsedArgs;
}

void printWarning(String warn) {
  stderr.writeln('''
!!!
!!! Warning! $warn
!!!
''');
}

void warnOnNoAssertions() {
  try {
    assert(false);
  } catch (e) {
    return;
  }

  printWarning("You didn't --enable-asserts!");
}

class ExceptionCategory {
  final String topOfStack;
  final List<MapEntry<String?, int>> exceptionCountPerPackage;

  ExceptionCategory(this.topOfStack, Map<String?, int> exceptions)
      : exceptionCountPerPackage = exceptions.entries.toList()
          ..sort((e1, e2) => e2.value.compareTo(e1.value));

  int get count => exceptionCountPerPackage.length;

  List<String?> get packageNames =>
      [for (var entry in exceptionCountPerPackage) entry.key];

  Iterable<String> get packageNamesAndCounts =>
      exceptionCountPerPackage.map((entry) => '${entry.key} x${entry.value}');

  String toString() => '$topOfStack (${packageNamesAndCounts.join(', ')})';
}

class _Listener implements NullabilityMigrationListener {
  /// Set this to `true` to cause just the exception nodes to be printed when
  /// `_Listener.categoryOfInterest` is non-null.  Set this to `false` to cause
  /// the full stack trace to be printed.
  final bool? printExceptionNodeOnly;

  /// Set this to a non-null value to cause any exception to be printed in full
  /// if its category contains the string.
  final String? categoryOfInterest;

  /// Exception mapped to a map of packages & exception counts.
  final groupedExceptions = <String, Map<String?, int>>{};

  int numExceptions = 0;

  int numTypesMadeNullable = 0;

  int numVariablesMarkedLate = 0;

  int numInsertedCasts = 0;

  int numInsertedParenthesis = 0;

  int numNullChecksAdded = 0;

  int numMetaImportsAdded = 0;

  int numRequiredAnnotationsAdded = 0;

  int numDeadCodeSegmentsFound = 0;

  int numOtherEdits = 0;

  String? currentPackage;

  _Listener(this.categoryOfInterest, {this.printExceptionNodeOnly = false});

  @override
  void addEdit(Source source, SourceEdit edit) {
    if (edit.replacement == '') {
      return;
    }

    if (edit.replacement.contains('!')) {
      ++numNullChecksAdded;
    }

    if (edit.replacement.contains('(')) {
      ++numInsertedParenthesis;
    }

    if (edit.replacement == '?' && edit.length == 0) {
      ++numTypesMadeNullable;
    } else if (edit.replacement == "import 'package:meta/meta.dart';\n" &&
        edit.length == 0) {
      ++numMetaImportsAdded;
    } else if (edit.replacement == 'required ' && edit.length == 0) {
      ++numRequiredAnnotationsAdded;
    } else if (edit.replacement == 'late ' && edit.length == 0) {
      ++numVariablesMarkedLate;
    } else if (edit.replacement.startsWith(' as ') && edit.length == 0) {
      ++numInsertedCasts;
    } else if ((edit.replacement == '/* ' ||
            edit.replacement == ' /*' ||
            edit.replacement == '; /*') &&
        edit.length == 0) {
      ++numDeadCodeSegmentsFound;
    } else if ((edit.replacement == '*/ ' ||
            edit.replacement == ' */' ||
            edit.replacement == ')' ||
            edit.replacement == '!' ||
            edit.replacement == '(') &&
        edit.length == 0) {
    } else {
      numOtherEdits++;
    }
  }

  @override
  void addSuggestion(String descriptions, Location location) {}

  @override
  void reportException(
      Source? source, AstNode? node, Object exception, StackTrace stackTrace) {
    var category = _classifyStackTrace(stackTrace.toString().split('\n'));
    String detail = '''
In file $source
While processing $node
Exception $exception
$stackTrace
''';
    if (categoryOfInterest != null && category.contains(categoryOfInterest!)) {
      if (printExceptionNodeOnly!) {
        print('$node');
      } else {
        print(detail);
      }
    }
    (groupedExceptions[category] ??= <String?, int>{})
        .update(currentPackage, (value) => ++value, ifAbsent: () => 1);
    ++numExceptions;
  }

  String _classifyStackTrace(List<String> stackTrace) {
    for (var entry in stackTrace) {
      if (entry.contains('EdgeBuilder._unimplemented')) continue;
      if (entry.contains('_AssertionError._doThrowNew')) continue;
      if (entry.contains('_AssertionError._throwNew')) continue;
      if (entry.contains('NodeBuilder._unimplemented')) continue;
      if (entry.contains('Object.noSuchMethod')) continue;
      if (entry.contains('List.[] (dart:core-patch/growable_array.dart')) {
        continue;
      }
      return entry;
    }
    return '???';
  }
}
