// 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.

/// This command allows to inspect information written into the
/// precompiler trace (`--trace-precompiler-to` output).
library vm_snapshot_analysis.explain;

import 'dart:async';
import 'dart:io';
import 'dart:math' as math;

import 'package:args/command_runner.dart';

import 'package:vm_snapshot_analysis/name.dart';
import 'package:vm_snapshot_analysis/precompiler_trace.dart';
import 'package:vm_snapshot_analysis/program_info.dart';
import 'package:vm_snapshot_analysis/utils.dart';

class ExplainCommand extends Command<void> {
  @override
  final name = 'explain';

  @override
  final description = '''
Explain why certain methods were pulled into the binary.
''';

  ExplainCommand() {
    addSubcommand(ExplainDynamicCallsCommand());
  }
}

/// Generates a summary report about dynamic calls sorted by approximation
/// of their retained size, i.e. the amount of bytes these calls are pulling
/// into the snapshot.
class ExplainDynamicCallsCommand extends Command<void> {
  @override
  final name = 'dynamic-calls';

  @override
  final description = '''
This command explains impact of the dynamic calls on the binary size.

It needs AOT snapshot size profile (an output of either
--write-v8-snapshot-profile-to or --print-instructions-sizes-to flags) and
precompiler trace (an output of --trace-precompiler-to flag).
''';

  ExplainCommand() {}

  @override
  Future<void> run() async {
    final sizesJson = File(argResults.rest[0]);
    if (!sizesJson.existsSync()) {
      usageException('Size profile ${sizesJson.path} does not exist!');
    }

    final traceJson = File(argResults.rest[1]);
    if (!traceJson.existsSync()) {
      usageException('Size profile ${traceJson.path} does not exist!');
    }

    final callGraph = await loadTrace(traceJson);
    callGraph.computeDominators();

    final programInfo = await loadProgramInfo(sizesJson);

    final histogram = Histogram.fromIterable<CallGraphNode>(
        callGraph.dynamicCalls, sizeOf: (dynamicCall) {
      // Compute approximate retained size by traversing the dominator tree
      // and consulting snapshot profile.
      var totalSize = 0;
      dynamicCall.visitDominatorTree((retained, depth) {
        if (retained.isFunctionNode) {
          // Note that call graph keeps private library keys intact in the
          // names (because we need to distinguish dynamic invocations
          // through with the same private name in different libraries).
          // So we need to scrub the path before we lookup information in the
          // profile.
          final path = (retained.data as ProgramInfoNode)
              .path
              .map((n) => Name(n).scrubbed)
              .toList();
          if (path.last.startsWith('[tear-off] ')) {
            // Tear-off forwarder is placed into the function that is torn so
            // we need to slightly tweak the path to be able to find it.
            path.insert(
                path.length - 1, path.last.replaceAll('[tear-off] ', ''));
          }
          final retainedSize = programInfo.lookup(path);
          totalSize += (retainedSize?.totalSize ?? 0);
        }
        return true;
      });
      return totalSize;
    }, bucketFor: (n) {
      return (n.data as String).replaceAll('dyn:', '');
    }, bucketInfo: BucketInfo(nameComponents: ['Selector']));

    printHistogram(programInfo, histogram,
        prefix: histogram.bySize.where((key) => histogram.buckets[key] > 0));

    // For top 10 dynamic selectors print the functions which contain these
    // dynamic calls.
    for (var selector
        in histogram.bySize.take(math.min(10, histogram.length))) {
      final dynSelector = 'dyn:$selector';
      final callNodes = callGraph.nodes
          .where((n) => n.data == selector || n.data == dynSelector);

      print('\nDynamic call to ${selector}'
          ' (retaining ~${histogram.buckets[selector]} bytes) occurs in:');
      for (var node in callNodes) {
        for (var pred in node.pred) {
          print('    ${pred.data.qualifiedName}');
        }
      }
    }
  }

  @override
  String get invocation =>
      super.invocation.replaceAll('[arguments]', '<sizes.json> <trace.json>');
}
