// Copyright (c) 2015, 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.

/// Command-line tool presenting how much each function contributes to the total
/// code.
library compiler.tool.live_code_size_analysis;

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

import 'package:dart2js_info/info.dart';
import 'package:dart2js_info/src/graph.dart';
import 'package:dart2js_info/src/util.dart';

main(args) {
  var json = JSON.decode(new File(args[0]).readAsStringSync());
  var info = new AllInfoJsonCodec().decode(json);
  showCodeDistribution(info);
}

showCodeDistribution(AllInfo info,
    {bool filter(Info info), bool showLibrarySizes: false}) {
  var realTotal = info.program.size;
  if (filter == null) filter = (i) => true;
  var reported = []
    ..addAll(info.functions.where(filter))
    ..addAll(info.fields.where(filter));

  // Compute a graph from the dependencies in [info].
  Graph<Info> graph = graphFromInfo(info);

  // Compute the strongly connected components and calculate their size.
  var components = graph.computeTopologicalSort();
  print('total elements: ${graph.nodes.length}');
  print('total strongly connected components: ${components.length}');
  var maxS = 0;
  var totalCount = graph.nodeCount;
  var minS = totalCount;
  var nodeData = {};
  for (var scc in components) {
    var sccData = new _SccData();
    maxS = math.max(maxS, scc.length);
    minS = math.min(minS, scc.length);
    for (var f in scc) {
      sccData.size += f.size;
      for (var g in graph.targetsOf(f)) {
        var gData = nodeData[g];
        if (gData != null) sccData.deps.add(gData);
      }
    }
    for (var f in scc) {
      nodeData[f] = sccData;
    }
  }
  print('scc sizes: min: $minS, max: $maxS, '
      'avg ${totalCount/components.length}');

  // Compute a dominator tree and calculate the size dominated by each element.
  // TODO(sigmund): we need a more reliable way to fetch main.
  var mainMethod = info.functions.firstWhere((f) => f.name == 'main');
  var dominatorTree = graph.dominatorTree(mainMethod);
  var dominatedSize = {};
  helper(n) {
    int size = n.size;
    assert(!dominatedSize.containsKey(n));
    dominatedSize[n] = 0;
    dominatorTree.targetsOf(n).forEach((m) {
      size += helper(m);
    });
    dominatedSize[n] = size;
    return size;
  }
  helper(mainMethod);
  reported.forEach((n) => dominatedSize.putIfAbsent(n, () => n.size));
  reported.sort((a, b) => (dominatedSize[b] + nodeData[b].maxSize) -
      (dominatedSize[a] + nodeData[a].maxSize));

  if (showLibrarySizes) {
    print(' --- Results per library ---');
    var totals = {};
    var longest = 0;
    reported.forEach((info) {
      var size = info.size;
      while (info != null && info is! LibraryInfo) {
        info = info.parent;
      }
      if (info == null) return;
      var name = info.name;
      totals.putIfAbsent(name, () => 0);
      totals[name] += size;
      longest = math.max(longest, name.length);
    });

    _showLibHeader(longest + 1);
    var reportedByLibrary = totals.keys.toList();
    reportedByLibrary.sort((a, b) => totals[b] - totals[a]);
    reportedByLibrary.forEach((name) {
      _showLib(name, totals[name], realTotal, longest + 1);
    });
  }

  print('\n --- Results per element (field or function) ---');
  _showElementHeader();
  reported.forEach((info) {
    var size = info.size;
    var min = dominatedSize[info];
    var max = nodeData[info].maxSize;
    _showElement(longName(info), size, min, max, realTotal);
  });
}

/// Data associated with an SCC. Used to compute the reachable code size.
class _SccData {
  int size = 0;
  Set deps = new Set();
  _SccData();

  int _maxSize;
  int get maxSize {
    compute();
    return _maxSize;
  }

  void compute() {
    if (_maxSize != null) return;
    var max = 0;
    var seen = new Set();
    helper(n) {
      if (!seen.add(n)) return;
      max += n.size;
      n.deps.forEach(helper);
    }
    helper(this);
    _maxSize = max;
  }
}

_showLibHeader(int namePadding) {
  print(' ${pad("Library", namePadding, right: true)}'
      ' ${pad("bytes", 8)} ${pad("%", 6)}');
}

_showLib(String msg, int size, int total, int namePadding) {
  var percent = (size * 100 / total).toStringAsFixed(2);
  print(' ${pad(msg, namePadding, right: true)}'
      ' ${pad(size, 8)} ${pad(percent, 6)}%');
}

_showElementHeader() {
  print('${pad("element size", 16)} '
      '${pad("dominated size", 18)} '
      '${pad("reachable size", 18)} '
      'Element identifier');
}

_showElement(String name, int size, int dominatedSize, int maxSize, int total) {
  var percent = (size * 100 / total).toStringAsFixed(2);
  var minPercent = (dominatedSize * 100 / total).toStringAsFixed(2);
  var maxPercent = (maxSize * 100 / total).toStringAsFixed(2);
  print('${pad(size, 8)} ${pad(percent, 6)}% '
      '${pad(dominatedSize, 10)} ${pad(minPercent, 6)}% '
      '${pad(maxSize, 10)} ${pad(maxPercent, 6)}% '
      '$name');
}
