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

/// Tool used mainly by dart2js developers to debug the generated info and check
/// that it is consistent and that it covers all the data we expect it to cover.
library dart2js_info.bin.debug_info;

import 'dart:convert';
import 'dart:io';

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

main(args) {
  if (args.length < 1) {
    print('usage: dart tool/debug_info.dart path-to-info.json '
        '[--show-library libname]');
    exit(1);
  }

  var filename = args[0];
  var json = JSON.decode(new File(filename).readAsStringSync());
  var info = new AllInfo.fromJson(json);
  var debugLibName;

  if (args.length > 2 && args[1] == '--show-library') {
    debugLibName = args[2];
  }

  // Gather data from visiting all info elements.
  var tracker = new _SizeTracker(debugLibName);
  info.accept(tracker);

  // Validate that listed elements include elements of each library.
  Set<Info> listed = new Set()..addAll(info.functions)..addAll(info.fields);
  // For our sanity we do some validation of dump-info invariants
  var diff1 = listed.difference(tracker.discovered);
  var diff2 = tracker.discovered.difference(listed);
  if (diff1.length == 0 || diff2.length == 0) {
    _pass('all fields and functions are covered');
  } else {
    if (diff1.length > 0) {
      _fail("some elements where listed globally that weren't part of any "
          "library (non-zero ${diff1.where((f) => f.size > 0).length})");
    }
    if (diff2.length > 0) {
      _fail("some elements found in libraries weren't part of the global list"
          " (non-zero ${diff2.where((f) => f.size > 0).length})");
    }
  }

  // Validate that code-size adds up.
  int realTotal = info.program.size;
  int totalLib = info.libraries.fold(0, (n, lib) => n + lib.size);
  int constantsSize = info.constants.fold(0, (n, c) => n + c.size);
  int accounted = totalLib + constantsSize;

  if (accounted != realTotal) {
    var percent =
        ((realTotal - accounted) * 100 / realTotal).toStringAsFixed(2);
    _fail('$percent% size missing: $accounted (all libs + consts) '
        '< $realTotal (total)');
  }
  var missingTotal = tracker.missing.values.fold(0, (a, b) => a + b);
  if (missingTotal > 0) {
    var percent = (missingTotal * 100 / realTotal).toStringAsFixed(2);
    _fail('$percent% size missing in libraries (sum of elements > lib.size)');
  }

  // Validate dependency data.
  compareGraphs(info);
}

class _SizeTracker extends RecursiveInfoVisitor {
  /// A library name for which to print debugging information (if not null).
  final String _debugLibName;

  _SizeTracker(this._debugLibName);

  /// [FunctionInfo]s and [FieldInfo]s transitively reachable from [LibraryInfo]
  /// elements.
  final Set<Info> discovered = new Set<Info>();

  /// Total number of bytes missing if you look at the reported size compared
  /// to the sum of the nested infos (e.g. if a class size is smaller than the
  /// sum of its methods). Used for validation and debugging of the dump-info
  /// invariants.
  final Map<Info, int> missing = {};

  /// Set of [FunctionInfo]s that appear to be unused by the app (they are not
  /// registed [coverage]).
  final List unused = [];

  /// Tracks the current state of this visitor.
  List<_State> stack = [new _State()];

  /// Code discovered for a [LibraryInfo], only used for debugging.
  final StringBuffer _debugCode = new StringBuffer();
  int _indent = 2;

  _push() => stack.add(new _State());

  void _pop(info) {
    var last = stack.removeLast();
    var size = last._totalSize;
    if (size > info.size) {
      // record dump-info inconsistencies.
      missing[info] = size - info.size;
    } else {
      // if size < info.size, that is OK, the enclosing element might have code
      // of it's own (e.g. a class declaration includes the name of the class,
      // but the discovered size only counts the size of the members.)
      size = info.size;
    }
    stack.last
      .._totalSize += size
      .._count += last._count
      .._bodySize += last._bodySize;
  }

  bool _debug = false;
  visitLibrary(LibraryInfo info) {
    if (_debugLibName != null) _debug = info.name.contains(_debugLibName);
    _push();
    if (_debug) {
      _debugCode.write('{\n');
      _indent = 4;
    }
    super.visitLibrary(info);
    _pop(info);
    if (_debug) {
      _debug = false;
      _indent = 4;
      _debugCode.write('}\n');
    }
  }

  _handleCodeInfo(info) {
    discovered.add(info);
    var code = info.code;
    if (_debug && code != null) {
      bool isClosureClass = info.name.endsWith('.call');
      if (isClosureClass) {
        var cname = info.name.substring(0, info.name.indexOf('.'));
        _debugCode.write(' ' * _indent);
        _debugCode.write(cname);
        _debugCode.write(': {\n');
        _indent += 2;
        _debugCode.write(' ' * _indent);
        _debugCode.write('...\n');
      }

      print('$info ${isClosureClass} \n${info.code}');
      _debugCode.write(' ' * _indent);
      var endsInNewLine = code.endsWith('\n');
      if (endsInNewLine) code = code.substring(0, code.length - 1);
      _debugCode.write(code.replaceAll('\n', '\n' + (' ' * _indent)));
      if (endsInNewLine) _debugCode.write(',\n');
      if (isClosureClass) {
        _indent -= 2;
        _debugCode.write(' ' * _indent);
        _debugCode.write('},\n');
      }
    }
    stack.last._totalSize += info.size;
    stack.last._bodySize += info.size;
    stack.last._count++;
  }

  visitField(FieldInfo info) {
    _handleCodeInfo(info);
    super.visitField(info);
  }

  visitFunction(FunctionInfo info) {
    _handleCodeInfo(info);
    super.visitFunction(info);
  }

  visitTypedef(TypedefInfo info) {
    if (_debug) print('$info');
    stack.last._totalSize += info.size;
    super.visitTypedef(info);
  }

  visitClass(ClassInfo info) {
    if (_debug) {
      print('$info');
      _debugCode.write(' ' * _indent);
      _debugCode.write('${info.name}: {\n');
      _indent += 2;
    }
    _push();
    super.visitClass(info);
    _pop(info);
    if (_debug) {
      _debugCode.write(' ' * _indent);
      _debugCode.write('},\n');
      _indent -= 2;
    }
  }
}

class _State {
  int _count = 0;
  int _totalSize = 0;
  int _bodySize = 0;
}

void compareGraphs(AllInfo info) {
  var g1 = new EdgeListGraph<Info>();
  var g2 = new EdgeListGraph<Info>();
  for (var f in info.functions) {
    g1.addNode(f);
    for (var g in f.uses) {
      g1.addEdge(f, g.target);
    }
    g2.addNode(f);
    if (info.dependencies[f] != null) {
      for (var g in info.dependencies[f]) {
        g2.addEdge(f, g);
      }
    }
  }

  for (var f in info.fields) {
    g1.addNode(f);
    for (var g in f.uses) {
      g1.addEdge(f, g.target);
    }
    g2.addNode(f);
    if (info.dependencies[f] != null) {
      for (var g in info.dependencies[f]) {
        g2.addEdge(f, g);
      }
    }
  }

  // Note: these checks right now show that 'uses' links are computed
  // differently than 'deps' links
  int inUsesNotInDependencies = 0;
  int inDependenciesNotInUses = 0;
  _sameEdges(f) {
    var targets1 = g1.targetsOf(f).toSet();
    var targets2 = g2.targetsOf(f).toSet();
    inUsesNotInDependencies += targets1.difference(targets2).length;
    inDependenciesNotInUses += targets2.difference(targets1).length;
  }
  info.functions.forEach(_sameEdges);
  info.fields.forEach(_sameEdges);
  if (inUsesNotInDependencies == 0 && inDependenciesNotInUses == 0) {
    _pass('dependency data is consistent');
  } else {
    _fail('inconsistencies in dependency data:\n'
        '   $inUsesNotInDependencies edges missing from "dependencies" graph\n'
        '   $inDependenciesNotInUses edges missing from "uses" graph');
  }
}

_pass(String msg) => print('\x1b[32mPASS\x1b[0m: $msg');
_fail(String msg) => print('\x1b[31mFAIL\x1b[0m: $msg');
