// 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 'package:args/command_runner.dart';
import 'package:dart2js_info/info.dart';
import 'package:dart2js_info/src/graph.dart';
import 'package:dart2js_info/src/io.dart';
import 'package:dart2js_info/src/util.dart';

import 'usage_exception.dart';

class DebugCommand extends Command<void> with PrintUsageException {
  @override
  final String name = "debug";
  @override
  final String description = "Dart2js-team diagnostics on a dump-info file.";

  DebugCommand() {
    argParser.addOption('show-library',
        help: "Show detailed data for a library with the given name");
  }

  @override
  void run() async {
    var args = argResults.rest;
    if (args.isEmpty) {
      usageException('Missing argument: info.data');
    }

    var info = await infoFromFile(args.first);
    var debugLibName = argResults['show-library'];

    validateSize(info, debugLibName);
    validateParents(info);
    compareGraphs(info);
    verifyDeps(info);
  }
}

/// Validates that codesize of elements adds up to total codesize.
validateSize(AllInfo info, String debugLibName) {
  // Gather data from visiting all info elements.
  var tracker = _SizeTracker(debugLibName);
  info.accept(tracker);

  // Validate that listed elements include elements of each library.
  final listed = {...info.functions, ...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.isEmpty || diff2.isEmpty) {
    _pass('all fields and functions are covered');
  } else {
    if (diff1.isNotEmpty) {
      _fail("some elements where listed globally that weren't part of any "
          "library (non-zero ${diff1.where((f) => f.size > 0).length})");
    }
    if (diff2.isNotEmpty) {
      _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)');
  }
  int 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)');
  }
}

/// Validates that every element in the model has a parent (except libraries).
validateParents(AllInfo info) {
  final parentlessInfos = <Info>{};

  failIfNoParents(List<Info> infos) {
    for (var info in infos) {
      if (info.parent == null) {
        parentlessInfos.add(info);
      }
    }
  }

  failIfNoParents(info.functions);
  failIfNoParents(info.typedefs);
  failIfNoParents(info.classes);
  failIfNoParents(info.classTypes);
  failIfNoParents(info.fields);
  failIfNoParents(info.closures);
  if (parentlessInfos.isEmpty) {
    _pass('all elements have a parent');
  } else {
    _fail('${parentlessInfos.length} elements have no parent');
  }
}

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 = <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 = [_State()];

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

  void _push() => stack.add(_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;
  @override
  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++;
  }

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

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

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

  @override
  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;
    }
  }

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

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

/// Validates that both forms of dependency information match.
void compareGraphs(AllInfo info) {
  var g1 = EdgeListGraph<Info>();
  var g2 = 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');
  }
}

// Validates that all elements are reachable from `main` in the dependency
// graph.
verifyDeps(AllInfo info) {
  var graph = graphFromInfo(info);
  var entrypoint = info.program.entrypoint;
  var reachables = Set.from(graph.preOrder(entrypoint));

  var functionsAndFields = <BasicInfo>[...info.functions, ...info.fields];
  var unreachables =
      functionsAndFields.where((func) => !reachables.contains(func));
  if (unreachables.isNotEmpty) {
    _fail('${unreachables.length} elements are unreachable from the '
        'entrypoint');
  } else {
    _pass('all elements are reachable from the entrypoint');
  }
}

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