// Copyright (c) 2020, 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' as io;

import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:args/args.dart';

/// Compute and print lexical and semantic information about a package.
Future<void> main(List<String> args) async {
  var parser = createArgParser();
  var result = parser.parse(args);

  if (validArguments(parser, result)) {
    var out = io.stdout;
    var rootPath = result.rest[0];
    out.writeln('Analyzing root: "$rootPath"');

    var computer = CodeShapeMetricsComputer();
    var stopwatch = Stopwatch();
    stopwatch.start();
    await computer.compute(rootPath);
    stopwatch.stop();
    var duration = Duration(milliseconds: stopwatch.elapsedMilliseconds);
    out.writeln('  Analysis performed in $duration');
    computer.writeResults(out);
    await out.flush();
  }
  io.exit(0);
}

/// Create a parser that can be used to parse the command-line arguments.
ArgParser createArgParser() {
  var parser = ArgParser();
  parser.addOption(
    'help',
    abbr: 'h',
    help: 'Print this help message.',
  );
  return parser;
}

/// Print usage information for this tool.
void printUsage(ArgParser parser, {String? error}) {
  if (error != null) {
    print(error);
    print('');
  }
  print('usage: dart code_metrics.dart [options] packagePath');
  print('');
  print('Compute and print lexical and semantic information about a package.');
  print('');
  print(parser.usage);
}

/// Return `true` if the command-line arguments (represented by the [result] and
/// parsed by the [parser]) are valid.
bool validArguments(ArgParser parser, ArgResults result) {
  if (result.wasParsed('help')) {
    printUsage(parser);
    return false;
  } else if (result.rest.length != 1) {
    printUsage(parser, error: 'No package path specified.');
    return false;
  }
  var rootPath = result.rest[0];
  if (!io.Directory(rootPath).existsSync()) {
    printUsage(parser, error: 'The directory "$rootPath" does not exist.');
    return false;
  }
  return true;
}

/// An object that records the data used to compute the metrics.
class CodeShapeData {
  /// A table mapping the name of a node class to the number of instances of
  /// that class that were visited.
  Map<String, int> nodeData = {};

  /// A table mapping the name of a node class and the name of the node's
  /// parent's class to the number of instances of the node class that had a
  /// parent of the parent class.
  Map<String, Map<String, int>> parentData = {};

  /// A table mapping the name of a node class, the name of a property of that
  /// node, and the class of the property's value to number of instances of the
  /// node class that had a value of the property class for the property.
  Map<String, Map<String, Map<String, int>>> childData = {};

  /// A table mapping the name of a node class, the name of a list-valued
  /// property of that node, and the length of the list to number of instances
  /// of the node class that had a value of that length for the property.
  Map<String, Map<String, Map<int, int>>> lengthData = {};

  /// Information about children of nodes that were not correctly recorded.
  Set<String> missedChildren = {};

  /// Initialize a newly created set of relevance data to be empty.
  CodeShapeData();

  /// Record that an element of the given [node] was found in the given
  /// [context].
  void recordNode(String nodeClassName, String property, AstNode node) {
    var childClass = node.runtimeType.toString();
    if (childClass.endsWith('Impl')) {
      childClass = childClass.substring(0, childClass.length - 4);
    }
    _recordChildData(nodeClassName, property, childClass);
  }

  /// Record that a node that is an instance of the [nodeClassName] was visited.
  void recordNodeClass(String nodeClassName) {
    nodeData[nodeClassName] = (nodeData[nodeClassName] ?? 0) + 1;
  }

  void recordNodeList(String nodeClassName, String property, NodeList list) {
    _recordListLength(nodeClassName, property, list);
    for (var element in list) {
      recordNode(nodeClassName, property, element);
    }
  }

  void recordParentClass(String nodeClassName, String parentClassName) {
    var classMap = parentData.putIfAbsent(nodeClassName, () => {});
    classMap[parentClassName] = (classMap[parentClassName] ?? 0) + 1;
  }

  void recordToken(String nodeClassName, String property, Token? token) {
    var lexeme = token?.lexeme ?? 'null';
    _recordChildData(nodeClassName, property, lexeme);
  }

  void _recordChildData(
      String nodeClassName, String property, String childValue) {
    var classMap = childData.putIfAbsent(nodeClassName, () => {});
    var propertyMap = classMap.putIfAbsent(property, () => {});
    propertyMap[childValue] = (propertyMap[childValue] ?? 0) + 1;
  }

  /// Record that an element of the given [node] was found in the given
  /// [context].
  void _recordListLength(String nodeClassName, String property, NodeList list) {
    var classMap = lengthData.putIfAbsent(nodeClassName, () => {});
    var propertyMap = classMap.putIfAbsent(property, () => {});
    var length = list.length;
    propertyMap[length] = (propertyMap[length] ?? 0) + 1;
  }
}

/// An object that visits a compilation unit in order to record the data used to
/// compute the metrics.
class CodeShapeDataCollector extends RecursiveAstVisitor<void> {
  /// The data being collected.
  final CodeShapeData data;

  /// Initialize a newly created collector to add data points to the given
  /// [data].
  CodeShapeDataCollector(this.data);

  @override
  void visitAdjacentStrings(AdjacentStrings node) {
    _visitChildren(node, {
      'strings': node.strings,
    });
    super.visitAdjacentStrings(node);
  }

  @override
  void visitAnnotation(Annotation node) {
    _visitChildren(node, {
      'name': node.name,
      'constructorName': node.constructorName,
      'arguments': node.arguments,
    });
    super.visitAnnotation(node);
  }

  @override
  void visitArgumentList(ArgumentList node) {
    _visitChildren(node, {
      'arguments': node.arguments,
    });
    super.visitArgumentList(node);
  }

  @override
  void visitAsExpression(AsExpression node) {
    _visitChildren(node, {
      'expression': node.expression,
      'type': node.type,
    });
    super.visitAsExpression(node);
  }

  @override
  void visitAssertInitializer(AssertInitializer node) {
    _visitChildren(node, {
      'condition': node.condition,
      'message': node.message,
    });
    super.visitAssertInitializer(node);
  }

  @override
  void visitAssertStatement(AssertStatement node) {
    _visitChildren(node, {
      'condition': node.condition,
      'message': node.message,
    });
    super.visitAssertStatement(node);
  }

  @override
  void visitAssignmentExpression(AssignmentExpression node) {
    _visitChildren(node, {
      'leftHandSide': node.leftHandSide,
      'operator': node.operator,
      'rightHandSide': node.rightHandSide,
    });
    super.visitAssignmentExpression(node);
  }

  @override
  void visitAwaitExpression(AwaitExpression node) {
    _visitChildren(node, {
      'expression': node.expression,
    });
    super.visitAwaitExpression(node);
  }

  @override
  void visitBinaryExpression(BinaryExpression node) {
    _visitChildren(node, {
      'leftOperand': node.leftOperand,
      'operator': node.operator,
      'rightOperand': node.rightOperand,
    });
    super.visitBinaryExpression(node);
  }

  @override
  void visitBlock(Block node) {
    _visitChildren(node, {
      'statement': node.statements,
    });
    super.visitBlock(node);
  }

  @override
  void visitBlockFunctionBody(BlockFunctionBody node) {
    _visitChildren(node, {
      'keyword': node.keyword,
      'star': node.star,
      'block': node.block,
    });
    super.visitBlockFunctionBody(node);
  }

  @override
  void visitBooleanLiteral(BooleanLiteral node) {
    _visitChildren(node, {
      'literal': node.literal,
    });
    super.visitBooleanLiteral(node);
  }

  @override
  void visitBreakStatement(BreakStatement node) {
    _visitChildren(node, {
      'label': node.label,
    });
    super.visitBreakStatement(node);
  }

  @override
  void visitCascadeExpression(CascadeExpression node) {
    _visitChildren(node, {
      'target': node.target,
      'cascadeSections': node.cascadeSections,
    });
    super.visitCascadeExpression(node);
  }

  @override
  void visitCatchClause(CatchClause node) {
    _visitChildren(node, {
      'exceptionType': node.exceptionType,
      'exceptionParameter': node.exceptionParameter,
      'stackTraceParameter': node.stackTraceParameter,
      'body': node.body,
    });
    super.visitCatchClause(node);
  }

  @override
  void visitClassDeclaration(ClassDeclaration node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'abstractKeyword': node.abstractKeyword,
      'name': node.name,
      'typeParameters': node.typeParameters,
      'extendsClause': node.extendsClause,
      'withClause': node.withClause,
      'implementsClause': node.implementsClause,
      'nativeClause': node.nativeClause,
      'members': node.members,
    });
    super.visitClassDeclaration(node);
  }

  @override
  void visitClassTypeAlias(ClassTypeAlias node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'abstractKeyword': node.abstractKeyword,
      'name': node.name,
      'typeParameters': node.typeParameters,
      'superclass': node.superclass2,
      'withClause': node.withClause,
      'implementsClause': node.implementsClause,
    });
    super.visitClassTypeAlias(node);
  }

  @override
  void visitComment(Comment node) {
    _visitChildren(node, {'references': node.references});
    super.visitComment(node);
  }

  @override
  void visitCommentReference(CommentReference node) {
    _visitChildren(node, {
      'newKeyword': node.newKeyword,
      'expression': node.expression,
    });
    super.visitCommentReference(node);
  }

  @override
  void visitCompilationUnit(CompilationUnit node) {
    _visitChildren(node, {
      'scriptTag': node.scriptTag,
      'directives': node.directives,
      'declarations': node.declarations,
    });
    super.visitCompilationUnit(node);
  }

  @override
  void visitConditionalExpression(ConditionalExpression node) {
    _visitChildren(node, {
      'condition': node.condition,
      'thenExpression': node.thenExpression,
      'elseExpression': node.elseExpression,
    });
    super.visitConditionalExpression(node);
  }

  @override
  void visitConfiguration(Configuration node) {
    _visitChildren(node, {
      'name': node.name,
      'value': node.value,
      'uri': node.uri,
    });
    super.visitConfiguration(node);
  }

  @override
  void visitConstructorDeclaration(ConstructorDeclaration node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'externalKeyword': node.externalKeyword,
      'constKeyword': node.constKeyword,
      'factoryKeyword': node.factoryKeyword,
      'returnType': node.returnType,
      'name': node.name,
      'parameters': node.parameters,
      'initializers': node.initializers,
      'redirectedConstructor': node.redirectedConstructor,
      'body': node.body,
    });
    super.visitConstructorDeclaration(node);
  }

  @override
  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
    _visitChildren(node, {
      'thisKeyword': node.thisKeyword,
      'fieldName': node.fieldName,
      'expression': node.expression,
    });
    super.visitConstructorFieldInitializer(node);
  }

  @override
  void visitConstructorName(ConstructorName node) {
    _visitChildren(node, {
      'type': node.type2,
      'name': node.name,
    });
    super.visitConstructorName(node);
  }

  @override
  void visitContinueStatement(ContinueStatement node) {
    _visitChildren(node, {
      'label': node.label,
    });
    super.visitContinueStatement(node);
  }

  @override
  void visitDeclaredIdentifier(DeclaredIdentifier node) {
    _visitChildren(node, {
      'keyword': node.keyword,
      'type': node.type,
      'identifier': node.identifier,
    });
    super.visitDeclaredIdentifier(node);
  }

  @override
  void visitDefaultFormalParameter(DefaultFormalParameter node) {
    _visitChildren(node, {
      'parameter': node.parameter,
      'defaultValue': node.defaultValue,
    });
    super.visitDefaultFormalParameter(node);
  }

  @override
  void visitDoStatement(DoStatement node) {
    _visitChildren(node, {
      'body': node.body,
      'condition': node.condition,
    });
    super.visitDoStatement(node);
  }

  @override
  void visitDottedName(DottedName node) {
    _visitChildren(node, {
      'components': node.components,
    });
    super.visitDottedName(node);
  }

  @override
  void visitDoubleLiteral(DoubleLiteral node) {
    _visitChildren(node, {});
    super.visitDoubleLiteral(node);
  }

  @override
  void visitEmptyFunctionBody(EmptyFunctionBody node) {
    _visitChildren(node, {});
    super.visitEmptyFunctionBody(node);
  }

  @override
  void visitEmptyStatement(EmptyStatement node) {
    _visitChildren(node, {});
    super.visitEmptyStatement(node);
  }

  @override
  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'name': node.name,
    });
    super.visitEnumConstantDeclaration(node);
  }

  @override
  void visitEnumDeclaration(EnumDeclaration node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'name': node.name,
      'constants': node.constants,
    });
    super.visitEnumDeclaration(node);
  }

  @override
  void visitExportDirective(ExportDirective node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'uri': node.uri,
      'configurations': node.configurations,
      'combinators': node.combinators,
    });
    super.visitExportDirective(node);
  }

  @override
  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
    _visitChildren(node, {
      'keyword': node.keyword,
      'star': node.star,
      'expression': node.expression,
    });
    super.visitExpressionFunctionBody(node);
  }

  @override
  void visitExpressionStatement(ExpressionStatement node) {
    _visitChildren(node, {
      'expression': node.expression,
    });
    super.visitExpressionStatement(node);
  }

  @override
  void visitExtendsClause(ExtendsClause node) {
    _visitChildren(node, {
      'superclass': node.superclass2,
    });
    super.visitExtendsClause(node);
  }

  @override
  void visitExtensionDeclaration(ExtensionDeclaration node) {
    _visitChildren(node, {
      'name': node.name,
      'typeParameters': node.typeParameters,
      'extendedType': node.extendedType,
      'member': node.members,
    });
    super.visitExtensionDeclaration(node);
  }

  @override
  void visitExtensionOverride(ExtensionOverride node) {
    _visitChildren(node, {
      'extensionName': node.extensionName,
      'typeArguments': node.typeArguments,
      'argumentList': node.argumentList,
    });
    super.visitExtensionOverride(node);
  }

  @override
  void visitFieldDeclaration(FieldDeclaration node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'abstractKeyword': node.abstractKeyword,
      'covariantKeyword': node.covariantKeyword,
      'externalKeyword': node.externalKeyword,
      'staticKeyword': node.staticKeyword,
      'fields': node.fields,
    });
    super.visitFieldDeclaration(node);
  }

  @override
  void visitFieldFormalParameter(FieldFormalParameter node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'keyword': node.keyword,
      'type': node.type,
      'thisKeyword': node.thisKeyword,
      'identifier': node.identifier,
      'typeParameters': node.typeParameters,
      'parameters': node.parameters,
      'question': node.question,
    });
    super.visitFieldFormalParameter(node);
  }

  @override
  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
    _visitChildren(node, {
      'loopVariable': node.loopVariable,
      'iterable': node.iterable,
    });
    super.visitForEachPartsWithDeclaration(node);
  }

  @override
  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
    _visitChildren(node, {
      'identifier': node.identifier,
      'iterable': node.iterable,
    });
    super.visitForEachPartsWithIdentifier(node);
  }

  @override
  void visitForElement(ForElement node) {
    _visitChildren(node, {
      'awaitKeyword': node.awaitKeyword,
      'forLoopParts': node.forLoopParts,
      'body': node.body,
    });
    super.visitForElement(node);
  }

  @override
  void visitFormalParameterList(FormalParameterList node) {
    _visitChildren(node, {
      'parameters': node.parameters,
    });
    super.visitFormalParameterList(node);
  }

  @override
  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
    _visitChildren(node, {
      'variables': node.variables,
      'condition': node.condition,
      'updater': node.updaters,
    });
    super.visitForPartsWithDeclarations(node);
  }

  @override
  void visitForPartsWithExpression(ForPartsWithExpression node) {
    _visitChildren(node, {
      'initialization': node.initialization,
      'condition': node.condition,
      'updater': node.updaters,
    });
    super.visitForPartsWithExpression(node);
  }

  @override
  void visitForStatement(ForStatement node) {
    _visitChildren(node, {
      'awaitKeyword': node.awaitKeyword,
      'forLoopParts': node.forLoopParts,
      'body': node.body,
    });
    super.visitForStatement(node);
  }

  @override
  void visitFunctionDeclaration(FunctionDeclaration node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'externalKeyword': node.externalKeyword,
      'propertyKeyword': node.propertyKeyword,
      'name': node.name,
      'functionExpression': node.functionExpression,
      'returnType': node.returnType,
    });
    super.visitFunctionDeclaration(node);
  }

  @override
  void visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
    _visitChildren(node, {
      'functionDeclaration': node.functionDeclaration,
    });
    super.visitFunctionDeclarationStatement(node);
  }

  @override
  void visitFunctionExpression(FunctionExpression node) {
    _visitChildren(node, {
      'typeParameters': node.typeParameters,
      'parameters': node.parameters,
      'body': node.body,
    });
    super.visitFunctionExpression(node);
  }

  @override
  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
    _visitChildren(node, {
      'function': node.function,
      'typeArguments': node.typeArguments,
      'argumentList': node.argumentList,
    });
    super.visitFunctionExpressionInvocation(node);
  }

  @override
  void visitFunctionTypeAlias(FunctionTypeAlias node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'returnType': node.returnType,
      'name': node.name,
      'typeParameters': node.typeParameters,
      'parameters': node.parameters,
    });
    super.visitFunctionTypeAlias(node);
  }

  @override
  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
    _visitChildren(node, {
      'covariantKeyword': node.covariantKeyword,
      'returnType': node.returnType,
      'identifier': node.identifier,
      'typeParameters': node.typeParameters,
      'parameters': node.parameters,
      'question': node.question,
    });
    super.visitFunctionTypedFormalParameter(node);
  }

  @override
  void visitGenericFunctionType(GenericFunctionType node) {
    _visitChildren(node, {
      'returnType': node.returnType,
      'typeParameters': node.typeParameters,
      'parameters': node.parameters,
      'question': node.question,
    });
    super.visitGenericFunctionType(node);
  }

  @override
  void visitGenericTypeAlias(GenericTypeAlias node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'name': node.name,
      'typeParameters': node.typeParameters,
      'functionType': node.functionType,
    });
    super.visitGenericTypeAlias(node);
  }

  @override
  void visitHideCombinator(HideCombinator node) {
    _visitChildren(node, {
      'hiddenNames': node.hiddenNames,
    });
    super.visitHideCombinator(node);
  }

  @override
  void visitIfElement(IfElement node) {
    _visitChildren(node, {
      'condition': node.condition,
      'thenElement': node.thenElement,
      'elseElement': node.elseElement,
    });
    super.visitIfElement(node);
  }

  @override
  void visitIfStatement(IfStatement node) {
    _visitChildren(node, {
      'condition': node.condition,
      'thenStatement': node.thenStatement,
      'elseStatement': node.elseStatement,
    });
    super.visitIfStatement(node);
  }

  @override
  void visitImplementsClause(ImplementsClause node) {
    _visitChildren(node, {
      'interfaces': node.interfaces2,
    });
    super.visitImplementsClause(node);
  }

  @override
  void visitImportDirective(ImportDirective node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'uri': node.uri,
      'deferredKeyword': node.deferredKeyword,
      'asKeyword': node.asKeyword,
      'prefix': node.prefix,
      'configurations': node.configurations,
      'combinators': node.combinators,
    });
    super.visitImportDirective(node);
  }

  @override
  void visitIndexExpression(IndexExpression node) {
    _visitChildren(node, {
      'target': node.target,
      'index': node.index,
    });
    super.visitIndexExpression(node);
  }

  @override
  void visitInstanceCreationExpression(InstanceCreationExpression node) {
    _visitChildren(node, {
      'keyword': node.keyword,
      'constructorName': node.constructorName,
      'argumentList': node.argumentList,
    });
    super.visitInstanceCreationExpression(node);
  }

  @override
  void visitIntegerLiteral(IntegerLiteral node) {
    var value = node.value;
    if (value == -1 || value == 0 || value == 1) {
      _visitChildren(node, {
        'literal': node.literal,
      });
    } else {
      _visitChildren(node, {});
    }
    super.visitIntegerLiteral(node);
  }

  @override
  void visitInterpolationExpression(InterpolationExpression node) {
    _visitChildren(node, {
      'expression': node.expression,
    });
    super.visitInterpolationExpression(node);
  }

  @override
  void visitInterpolationString(InterpolationString node) {
    _visitChildren(node, {});
    super.visitInterpolationString(node);
  }

  @override
  void visitIsExpression(IsExpression node) {
    _visitChildren(node, {
      'expression': node.expression,
      'type': node.type,
    });
    super.visitIsExpression(node);
  }

  @override
  void visitLabel(Label node) {
    _visitChildren(node, {
      'label': node.label,
    });
    super.visitLabel(node);
  }

  @override
  void visitLabeledStatement(LabeledStatement node) {
    _visitChildren(node, {
      'statement': node.statement,
    });
    super.visitLabeledStatement(node);
  }

  @override
  void visitLibraryDirective(LibraryDirective node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'name': node.name,
    });
    super.visitLibraryDirective(node);
  }

  @override
  void visitLibraryIdentifier(LibraryIdentifier node) {
    _visitChildren(node, {
      'components': node.components,
    });
    super.visitLibraryIdentifier(node);
  }

  @override
  void visitListLiteral(ListLiteral node) {
    _visitChildren(node, {
      'typeArguments': node.typeArguments,
      'elements': node.elements,
    });
    super.visitListLiteral(node);
  }

  @override
  void visitMapLiteralEntry(MapLiteralEntry node) {
    _visitChildren(node, {
      'key': node.key,
      'value': node.value,
    });
    super.visitMapLiteralEntry(node);
  }

  @override
  void visitMethodDeclaration(MethodDeclaration node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'externalKeyword': node.externalKeyword,
      'modifierKeyword': node.modifierKeyword,
      'returnType': node.returnType,
      'name': node.name,
      'operatorKeyword': node.operatorKeyword,
      'typeParameters': node.typeParameters,
      'parameters': node.parameters,
      'body': node.body,
    });
    super.visitMethodDeclaration(node);
  }

  @override
  void visitMethodInvocation(MethodInvocation node) {
    _visitChildren(node, {
      'target': node.target,
      'methodName': node.methodName,
      'typeArguments': node.typeArguments,
      'argumentList': node.argumentList,
    });
    super.visitMethodInvocation(node);
  }

  @override
  void visitMixinDeclaration(MixinDeclaration node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'name': node.name,
      'typeParameters': node.typeParameters,
      'onClause': node.onClause,
      'implementsClause': node.implementsClause,
      'members': node.members,
    });
    super.visitMixinDeclaration(node);
  }

  @override
  void visitNamedExpression(NamedExpression node) {
    _visitChildren(node, {
      'name': node.name,
      'expression': node.expression,
    });
    super.visitNamedExpression(node);
  }

  @override
  void visitNamedType(NamedType node) {
    _visitChildren(node, {
      'name': node.name,
      'typeArguments': node.typeArguments,
      'question': node.question,
    });
    super.visitNamedType(node);
  }

  @override
  void visitNativeClause(NativeClause node) {
    _visitChildren(node, {
      'name': node.name,
    });
    super.visitNativeClause(node);
  }

  @override
  void visitNativeFunctionBody(NativeFunctionBody node) {
    _visitChildren(node, {});
    super.visitNativeFunctionBody(node);
  }

  @override
  void visitNullLiteral(NullLiteral node) {
    _visitChildren(node, {});
    super.visitNullLiteral(node);
  }

  @override
  void visitOnClause(OnClause node) {
    _visitChildren(node, {
      'superclassConstraints': node.superclassConstraints2,
    });
    super.visitOnClause(node);
  }

  @override
  void visitParenthesizedExpression(ParenthesizedExpression node) {
    _visitChildren(node, {
      'expression': node.expression,
    });
    super.visitParenthesizedExpression(node);
  }

  @override
  void visitPartDirective(PartDirective node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'uri': node.uri,
    });
    super.visitPartDirective(node);
  }

  @override
  void visitPartOfDirective(PartOfDirective node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'libraryName': node.libraryName,
      'uri': node.uri,
    });
    super.visitPartOfDirective(node);
  }

  @override
  void visitPostfixExpression(PostfixExpression node) {
    _visitChildren(node, {
      'operand': node.operand,
      'operator': node.operator,
    });
    super.visitPostfixExpression(node);
  }

  @override
  void visitPrefixedIdentifier(PrefixedIdentifier node) {
    _visitChildren(node, {
      'prefix': node.prefix,
      'identifier': node.identifier,
    });
    super.visitPrefixedIdentifier(node);
  }

  @override
  void visitPrefixExpression(PrefixExpression node) {
    _visitChildren(node, {
      'operator': node.operator,
      'operand': node.operand,
    });
    super.visitPrefixExpression(node);
  }

  @override
  void visitPropertyAccess(PropertyAccess node) {
    _visitChildren(node, {
      'target': node.target,
      'propertyName': node.propertyName,
    });
    super.visitPropertyAccess(node);
  }

  @override
  void visitRedirectingConstructorInvocation(
      RedirectingConstructorInvocation node) {
    _visitChildren(node, {
      'constructorName': node.constructorName,
      'argumentList': node.argumentList,
    });
    super.visitRedirectingConstructorInvocation(node);
  }

  @override
  void visitRethrowExpression(RethrowExpression node) {
    _visitChildren(node, {});
    super.visitRethrowExpression(node);
  }

  @override
  void visitReturnStatement(ReturnStatement node) {
    _visitChildren(node, {
      'expression': node.expression,
    });
    super.visitReturnStatement(node);
  }

  @override
  void visitScriptTag(ScriptTag node) {
    _visitChildren(node, {});
    super.visitScriptTag(node);
  }

  @override
  void visitSetOrMapLiteral(SetOrMapLiteral node) {
    _visitChildren(node, {
      'typeArguments': node.typeArguments,
      'elements': node.elements,
    });
    super.visitSetOrMapLiteral(node);
  }

  @override
  void visitShowCombinator(ShowCombinator node) {
    _visitChildren(node, {
      'shownNames': node.shownNames,
    });
    super.visitShowCombinator(node);
  }

  @override
  void visitSimpleFormalParameter(SimpleFormalParameter node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'covariantKeyword': node.covariantKeyword,
      'keyword': node.keyword,
      'type': node.type,
      'identifier': node.identifier,
    });
    super.visitSimpleFormalParameter(node);
  }

  @override
  void visitSimpleStringLiteral(SimpleStringLiteral node) {
    _visitChildren(node, {});
    super.visitSimpleStringLiteral(node);
  }

  @override
  void visitSpreadElement(SpreadElement node) {
    _visitChildren(node, {
      'expression': node.expression,
    });
    super.visitSpreadElement(node);
  }

  @override
  void visitStringInterpolation(StringInterpolation node) {
    _visitChildren(node, {
      'elements': node.elements,
    });
    super.visitStringInterpolation(node);
  }

  @override
  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
    _visitChildren(node, {
      'constructorName': node.constructorName,
      'argumentList': node.argumentList,
    });
    super.visitSuperConstructorInvocation(node);
  }

  @override
  void visitSuperExpression(SuperExpression node) {
    _visitChildren(node, {});
    super.visitSuperExpression(node);
  }

  @override
  void visitSwitchCase(SwitchCase node) {
    _visitChildren(node, {
      'labels': node.labels,
      'expression': node.expression,
      'statements': node.statements,
    });
    super.visitSwitchCase(node);
  }

  @override
  void visitSwitchDefault(SwitchDefault node) {
    _visitChildren(node, {
      'statements': node.statements,
    });
    super.visitSwitchDefault(node);
  }

  @override
  void visitSwitchStatement(SwitchStatement node) {
    _visitChildren(node, {
      'expression': node.expression,
      'members': node.members,
    });
    super.visitSwitchStatement(node);
  }

  @override
  void visitSymbolLiteral(SymbolLiteral node) {
    _visitChildren(node, {});
    super.visitSymbolLiteral(node);
  }

  @override
  void visitThisExpression(ThisExpression node) {
    _visitChildren(node, {});
    super.visitThisExpression(node);
  }

  @override
  void visitThrowExpression(ThrowExpression node) {
    _visitChildren(node, {
      'expression': node.expression,
    });
    super.visitThrowExpression(node);
  }

  @override
  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'externalKeyword': node.externalKeyword,
      'variables': node.variables,
    });
    super.visitTopLevelVariableDeclaration(node);
  }

  @override
  void visitTryStatement(TryStatement node) {
    _visitChildren(node, {
      'body': node.body,
      'catchClauses': node.catchClauses,
      'finallyBlock': node.finallyBlock,
    });
    super.visitTryStatement(node);
  }

  @override
  void visitTypeArgumentList(TypeArgumentList node) {
    _visitChildren(node, {
      'arguments': node.arguments,
    });
    super.visitTypeArgumentList(node);
  }

  @override
  void visitTypeParameter(TypeParameter node) {
    _visitChildren(node, {
      'name': node.name,
      'bound': node.bound,
    });
    super.visitTypeParameter(node);
  }

  @override
  void visitTypeParameterList(TypeParameterList node) {
    _visitChildren(node, {'typeParameters': node.typeParameters});
    super.visitTypeParameterList(node);
  }

  @override
  void visitVariableDeclaration(VariableDeclaration node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'name': node.name,
      'initializer': node.initializer,
    });
    super.visitVariableDeclaration(node);
  }

  @override
  void visitVariableDeclarationList(VariableDeclarationList node) {
    _visitChildren(node, {
      'documentationComment': node.documentationComment,
      'metadata': node.metadata,
      'type': node.type,
      'variables': node.variables,
    });
    super.visitVariableDeclarationList(node);
  }

  @override
  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
    _visitChildren(node, {
      'variables': node.variables,
    });
    super.visitVariableDeclarationStatement(node);
  }

  @override
  void visitWhileStatement(WhileStatement node) {
    _visitChildren(node, {
      'condition': node.condition,
      'body': node.body,
    });
    super.visitWhileStatement(node);
  }

  @override
  void visitWithClause(WithClause node) {
    _visitChildren(node, {
      'mixinTypes': node.mixinTypes2,
    });
    super.visitWithClause(node);
  }

  @override
  void visitYieldStatement(YieldStatement node) {
    _visitChildren(node, {
      'star': node.star,
      'expression': node.expression,
    });
    super.visitYieldStatement(node);
  }

  String _className(AstNode node) {
    var className = node.runtimeType.toString();
    if (className.endsWith('Impl')) {
      className = className.substring(0, className.length - 4);
    }
    return className;
  }

  /// Visit the children of a node. The node is an instance of the class named
  /// [parentClass] and the children are in the [childMap], keyed by the name of
  /// the child property.
  void _visitChildren(AstNode node, Map<String, Object?> childMap) {
    var nodeClassName = _className(node);

    data.recordNodeClass(nodeClassName);

    var parent = node.parent;
    if (parent != null) {
      data.recordParentClass(nodeClassName, _className(parent));
    }

    var visitChildren = <AstNode>[];
    for (var entry in childMap.entries) {
      var property = entry.key;
      var child = entry.value;
      if (child is AstNode) {
        data.recordNode(nodeClassName, property, child);
        visitChildren.add(child);
      } else if (child is NodeList) {
        data.recordNodeList(nodeClassName, property, child);
        visitChildren.addAll(child);
      } else if (child is Token?) {
        data.recordToken(nodeClassName, property, child);
      } else {
        throw ArgumentError('Unknown class of child: ${child.runtimeType}');
      }
    }
    // Validate that all AST node children were included in the [childMap].
    for (var entity in node.childEntities) {
      if (entity is AstNode && !visitChildren.contains(entity)) {
        data.missedChildren.add('$nodeClassName (${entity.runtimeType})');
      }
    }
  }
}

/// An object used to compute metrics for a single file or directory.
class CodeShapeMetricsComputer {
  /// The metrics data that was computed.
  final CodeShapeData data = CodeShapeData();

  /// Initialize a newly created metrics computer that can compute the metrics
  /// in one or more files and directories.
  CodeShapeMetricsComputer();

  /// Compute the metrics for the file(s) in the [rootPath].
  Future<void> compute(String rootPath) async {
    final collection = AnalysisContextCollection(
      includedPaths: [rootPath],
      resourceProvider: PhysicalResourceProvider.INSTANCE,
    );
    final collector = CodeShapeDataCollector(data);
    for (var context in collection.contexts) {
      await _computeInContext(context.contextRoot, collector);
    }
  }

  /// Write a report of the metrics that were computed to the [sink].
  void writeResults(StringSink sink) {
    // Write error information.
    _writeMissedChildren(sink);

    // Write normal information.
    _writeChildData(sink);
  }

  /// Compute the metrics for the files in the context [root], creating a
  /// separate context collection to prevent accumulating memory. The metrics
  /// should be captured in the [collector]. Include additional details in the
  /// output if [verbose] is `true`.
  Future<void> _computeInContext(
      ContextRoot root, CodeShapeDataCollector collector) async {
    // Create a new collection to avoid consuming large quantities of memory.
    final collection = AnalysisContextCollection(
      includedPaths: root.includedPaths.toList(),
      excludedPaths: root.excludedPaths.toList(),
      resourceProvider: PhysicalResourceProvider.INSTANCE,
    );
    var context = collection.contexts[0];
    var pathContext = context.contextRoot.resourceProvider.pathContext;
    for (var filePath in context.contextRoot.analyzedFiles()) {
      if (file_paths.isDart(pathContext, filePath)) {
        try {
          var resolvedUnitResult =
              await context.currentSession.getResolvedUnit(filePath);
          //
          // Check for errors that cause the file to be skipped.
          //
          if (resolvedUnitResult is! ResolvedUnitResult) {
            print('File $filePath skipped because it could not be analyzed.');
            print('');
            continue;
          } else if (hasError(resolvedUnitResult)) {
            print('File $filePath skipped due to errors:');
            for (var error in resolvedUnitResult.errors) {
              print('  ${error.toString()}');
            }
            print('');
            continue;
          }

          resolvedUnitResult.unit.accept(collector);
        } catch (exception) {
          print('Exception caught analyzing: "$filePath"');
          print(exception.toString());
        }
      }
    }
  }

  /// Convert the contents of a single [map] into the values for each row in the
  /// column occupied by the map.
  List<String> _convertMap<T extends Object>(String context, Map<T, int> map) {
    var columns = <String>[];
    var entries = map.entries.toList()
      ..sort((first, second) {
        return second.value.compareTo(first.value);
      });
    var total = 0;
    for (var entry in entries) {
      total += entry.value;
    }
    columns.add('$context ($total)');
    for (var entry in entries) {
      var value = entry.value;
      var percent = _formatPercent(value, total);
      columns.add('  $percent%: ${entry.key} ($value)');
    }
    return columns;
  }

  /// Compute and format a percentage for the fraction [value] / [total].
  String _formatPercent(int value, int total) {
    var percent = ((value / total) * 100).toStringAsFixed(1);
    if (percent.length == 3) {
      percent = '  $percent';
    } else if (percent.length == 4) {
      percent = ' $percent';
    }
    return percent;
  }

  /// Write the child data to the [sink].
  void _writeChildData(StringSink sink) {
    sink.writeln('');
    sink.writeln('Child data');

    // TODO(brianwilkerson) This misses all node kinds for which zero instances
    //  were visited.
    var nodeData = data.nodeData;
    var parentData = data.parentData;
    var childData = data.childData;
    var lengthData = data.lengthData;
    var nodeClasses = nodeData.keys.toList()..sort();
    for (var nodeClass in nodeClasses) {
      var count = nodeData[nodeClass];
      sink.writeln();
      sink.writeln('$nodeClass ($count)');

      var parentMap = parentData[nodeClass];
      if (parentMap != null) {
        var lines = _convertMap('parent', parentMap);
        for (var line in lines) {
          sink.writeln('  $line');
        }
      }

      var childMap = childData[nodeClass] ?? {};
      var listMap = lengthData[nodeClass] ?? {};
      var childNames = {...childMap.keys, ...listMap.keys}.toList()..sort();
      for (var childName in childNames) {
        var listLengths = listMap[childName];
        if (listLengths != null) {
          var lines = _convertMap(childName, listLengths);
          for (var line in lines) {
            sink.writeln('  $line');
          }
        }

        var childTypes = childMap[childName];
        if (childTypes != null) {
          var lines = _convertMap(childName, childTypes);
          for (var line in lines) {
            sink.writeln('  $line');
          }
        }
      }
    }
  }

  /// Write a report of the metrics that were computed to the [sink].
  void _writeMissedChildren(StringSink sink) {
    var missedChildren = data.missedChildren;
    if (missedChildren.isNotEmpty) {
      sink.writeln();
      sink.writeln('Missed children in the following classes:');
      for (var nodeClass in missedChildren.toList()..sort()) {
        sink.writeln('  $nodeClass');
      }
    }
  }

  /// Return `true` if the [result] contains an error.
  static bool hasError(ResolvedUnitResult result) {
    for (var error in result.errors) {
      if (error.severity == Severity.error) {
        return true;
      }
    }
    return false;
  }
}
