// Copyright (c) 2018, 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 tool creates interactive navigatable binary size reports from
/// JSON file generated by the AOT compiler's --print-instructions-sizes-to
/// flag.
///
/// It used the same visualization framework as Chromium's binary_size tool
/// located in runtime/third_party/binary_size.
library vm_snapshot_analysis.commands.treemap;

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';

import 'package:args/command_runner.dart';
import 'package:path/path.dart' as p;
import 'package:vm_snapshot_analysis/treemap.dart';

import 'utils.dart';

class TreemapCommand extends Command<void> {
  @override
  final name = 'treemap';

  @override
  final description = '''
Create interactive treemap from snapshot profiling information.

This tool is used to process snapshot size reports produced by
--print-instructions-sizes-to and --write-v8-snapshot-profile-to flags.

It will create an interactive web-page in the output-directory which can be
viewed in a browser:

\$ google-chrome <output-directory>/index.html''';

  @override
  String get invocation => super
      .invocation
      .replaceAll('[arguments]', '<symbol-sizes.json> <output-directory>');

  TreemapCommand() {
    // [argParser] is automatically created by the parent class.
    argParser
      ..addFlag('force',
          abbr: 'f',
          help: 'Force overwrite output directory even if it already exists')
      ..addOption('format',
          help: 'Specifies granularity of the treemap output',
          allowed: _formatFromString.keys,
          defaultsTo: _formatFromString.keys.first);
  }

  @override
  Future<void> run() async {
    final args = argResults!;

    if (args.rest.length != 2) {
      usageException('Need to specify input JSON and output directory.');
    }

    final input = File(args.rest[0]);
    final outputDir = Directory(args.rest[1]);

    if (!input.existsSync()) {
      usageException('Input file ${input.path} does not exist!');
    }

    if (outputDir.existsSync() && !args['force']) {
      usageException(
          'Output directory ${outputDir.path} already exists, specify --force to ignore.');
    }

    await generateTreeMap(input, outputDir,
        format: _formatFromString[args['format']] ??
            (throw 'Unrecognized format ${args['format']}'));
  }

  // Note: the first key in this map is the default format.
  static const _formatFromString = {
    'object-type': TreemapFormat.objectType,
    'data-and-code': TreemapFormat.dataAndCode,
    'collapsed': TreemapFormat.collapsed,
    'simplified': TreemapFormat.simplified,
  };
}

Future<void> generateTreeMap(File input, Directory outputDir,
    {TreemapFormat format = TreemapFormat.objectType}) async {
  // Load symbols data produced by the AOT compiler and convert it to
  // a tree.
  final inputJson = await loadJsonFromFile(input);
  final tree = treemapFromJson(inputJson, format: format);

  // Create output directory and copy all auxiliary files from binary_size tool.
  await outputDir.create(recursive: true);

  final assetsUri = (await Isolate.resolvePackageUri(
      Uri.parse('package:vm_snapshot_analysis/src/assets')))!;
  final assetsDir = assetsUri.toFilePath();
  final d3SrcDir = p.join(assetsDir, 'd3', 'src');

  final d3OutDir = p.join(outputDir.path, 'd3');
  await Directory(d3OutDir).create(recursive: true);

  for (var file in ['LICENSE', 'd3.js']) {
    await copyFile(d3SrcDir, file, d3OutDir);
  }
  for (var file in ['index.html', 'D3SymbolTreeMap.js']) {
    await copyFile(assetsDir, file, outputDir.path);
  }

  // Serialize symbol size tree as JSON.
  final dataJsPath = p.join(outputDir.path, 'data.js');
  final sink = File(dataJsPath).openWrite();
  sink.write('var tree_data=');
  await sink.addStream(Stream<Object?>.fromIterable([tree])
      .transform(json.encoder.fuse(utf8.encoder)));
  await sink.close();

  // Done.
  print('Generated ${p.toUri(p.absolute(outputDir.path, 'index.html'))}');
}

/// Copy file with the given name from [fromDir] to [toDir].
Future<void> copyFile(String fromDir, String name, String toDir) async {
  await File(p.join(fromDir, name)).copy(p.join(toDir, name));
}
