// 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/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';

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, 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).lineInfo;
      var migration =
          NullabilityMigration(listener, getLineInfo, permissive: true);
      for (var file in localFiles) {
        var resolvedUnit = await session.getResolvedUnit(file);
        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);
        if (!resolvedUnit.errors.any((e) => e.severity == Severity.error)) {
          migration.processInput(resolvedUnit);
        }
      }
      for (var file in localFiles) {
        var resolvedUnit = await session.getResolvedUnit(file);
        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 '???';
  }
}
