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

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math' show max;

import 'package:path/path.dart' as p;

void main(List<String> args) async {
  if (args.length != 2) {
    print(r"""
Usage: run_binary_size_analysis.dart <symbol-sizes.json> <output-directory>

This tool is used to process snapshot size reports produced by
--print-instructions-sizes-to=symbol-sizes.json.

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

$ google-chrome <output-directory>/index.html
""");
    exit(-1);
  }

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

  // Load symbols data produced by the AOT compiler and convert it to
  // a tree.
  final symbols = await input
      .openRead()
      .transform(utf8.decoder)
      .transform(json.decoder)
      .first;

  final root = {'n': '', 'children': {}, 'k': kindPath, 'maxDepth': 0};
  for (var symbol in symbols) {
    final name = symbol['n'];
    final size = symbol['s'];

    if (symbol.containsKey('c')) {
      final libraryUri = symbol['l'];
      final className = symbol['c'];
      addSymbol(root, '${libraryUri}/${className}', name, size);
    } else {
      addSymbol(root, '@stubs', name, size);
    }
  }
  final tree = flatten(root);

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

  final scriptLocation = p.dirname(Platform.script.toFilePath());
  final sdkRoot = p.join(scriptLocation, '..', '..', '..');
  final d3SrcDir = p.join(sdkRoot, 'runtime', 'third_party', 'd3', 'src');
  final templateDir = p.join(
      sdkRoot, 'runtime', 'third_party', 'binary_size', 'src', 'template');

  final d3OutDir = p.join(outputDir.path, 'd3');
  await new 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(templateDir, file, outputDir.path);
  }

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

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

const kindSymbol = 's';
const kindPath = 'p';
const kindBucket = 'b';
const symbolTypeGlobalText = 'T';

/// Create a child with the given name within the given node or return
/// an existing child.
Map<String, dynamic> addChild(
    Map<String, dynamic> node, String kind, String name) {
  return node['children'].putIfAbsent(name, () {
    final n = <String, dynamic>{'n': name, 'k': kind};
    if (kind != kindSymbol) {
      n['children'] = {};
    }
    return n;
  });
}

/// Add the given symbol to the tree.
void addSymbol(Map<String, dynamic> root, String path, String name, int size) {
  var node = root;
  var depth = 0;
  for (var part in path.split('/')) {
    node = addChild(node, kindPath, part);
    depth++;
  }
  node['lastPathElement'] = true;
  node = addChild(node, kindBucket, symbolTypeGlobalText);
  node['t'] = symbolTypeGlobalText;
  node = addChild(node, kindSymbol, name);
  node['t'] = symbolTypeGlobalText;
  node['value'] = size;
  depth += 2;
  root['maxDepth'] = max(root['maxDepth'], depth);
}

/// Convert all children entries from maps to lists.
Map<String, dynamic> flatten(Map<String, dynamic> node) {
  dynamic children = node['children'];
  if (children != null) {
    children = children.values.map((dynamic v) => flatten(v)).toList();
    node['children'] = children;
    if (children.length == 1 && children.first['k'] == 'p') {
      final singleChild = children.first;
      singleChild['n'] = '${node['n']}/${singleChild['n']}';
      return singleChild;
    }
  }
  return node;
}

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