// 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:path/path.dart' as p;
import 'package:args/command_runner.dart';
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 {
    if (argResults.rest.length != 2) {
      usageException('Need to specify input JSON and output directory.');
    }

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

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

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

    await generateTreeMap(input, outputDir,
        format: _formatFromString[argResults['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));
}
