// 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<int>(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));
}
