// Copyright (c) 2016, 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.
library kernel.treeshaker_dump;

import 'dart:io';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/transformations/treeshaker.dart';
import 'package:args/args.dart';
import 'package:path/path.dart' as pathlib;
import 'package:kernel/text/ast_to_text.dart';

ArgParser parser = new ArgParser(allowTrailingOptions: true)
  ..addFlag('used', help: 'Print used members', negatable: false)
  ..addFlag('unused', help: 'Print unused members', negatable: false)
  ..addFlag('instantiated',
      help: 'Print instantiated classes', negatable: false)
  ..addFlag('types', help: 'Print classes used as a type', negatable: false)
  ..addFlag('summary',
      help: 'Print short summary of tree shaking results', defaultsTo: true)
  ..addFlag('diff',
      help: 'Print textual output before and after tree shaking.\n'
          'Files are written to FILE.before.txt and FILE.after.txt',
      negatable: false)
  ..addOption('output',
      help: 'The --diff files are written to the given directory instead of '
          'the working directory')
  ..addFlag('legacy-mode', help: 'Run the tree shaker in legacy mode');

String usage = '''
Usage: treeshaker_dump [options] FILE.dill

Runs tree shaking on the given component and prints information about the results.

Example:
  treeshaker_dump --instantiated foo.dill

Example:
    treeshaker_dump --diff foo.dill
    diff -cd foo.{before,after}.txt > diff.txt
    # open diff.txt in an editor

Options:
${parser.usage}
''';

main(List<String> args) {
  if (args.isEmpty) {
    print(usage);
    exit(1);
  }
  ArgResults options = parser.parse(args);
  if (options.rest.length != 1) {
    print('Exactly one file should be given.');
    exit(1);
  }
  String filename = options.rest.single;

  if (options['output'] != null && !options['diff']) {
    print('--output must be used with --diff');
    exit(1);
  }

  bool legacyMode = options['legacy-mode'];

  Component component = loadComponentFromBinary(filename);
  CoreTypes coreTypes = new CoreTypes(component);
  ClassHierarchy hierarchy = new ClassHierarchy(component);
  TreeShaker shaker =
      new TreeShaker(coreTypes, hierarchy, component, legacyMode: legacyMode);
  int totalClasses = 0;
  int totalInstantiationCandidates = 0;
  int totalMembers = 0;
  int usedClasses = 0;
  int instantiatedClasses = 0;
  int usedMembers = 0;

  void visitMember(Member member) {
    if (member.isAbstract) return; // Abstract members are not relevant.
    ++totalMembers;
    bool isUsed = shaker.isMemberBodyUsed(member);
    if (isUsed) {
      ++usedMembers;
    }
    if (isUsed && options['used'] || !isUsed && options['unused']) {
      String prefix = (options['used'] && options['unused'])
          ? (isUsed ? 'USED   ' : 'UNUSED ')
          : '';
      print('$prefix$member');
    }
  }

  for (var library in component.libraries) {
    library.members.forEach(visitMember);
    for (Class classNode in library.classes) {
      ++totalClasses;
      if (shaker.isInstantiated(classNode)) {
        ++instantiatedClasses;
        ++totalInstantiationCandidates;
      } else if (!classNode.isAbstract &&
          classNode.members.any((m) => m.isInstanceMember)) {
        ++totalInstantiationCandidates;
      }
      if (shaker.isHierarchyUsed(classNode)) {
        ++usedClasses;
      }
      classNode.members.forEach(visitMember);
      if (options['instantiated'] && shaker.isInstantiated(classNode)) {
        print(classNode);
      }
      if (options['types'] && shaker.isHierarchyUsed(classNode)) {
        print(classNode);
      }
    }
  }

  if (options['summary']) {
    print('Classes used:         ${ratio(usedClasses, totalClasses)}');
    print('Classes instantiated: '
        '${ratio(instantiatedClasses, totalInstantiationCandidates)}');
    print('Members used:         ${ratio(usedMembers, totalMembers)}');
  }

  if (options['diff']) {
    String name = pathlib.basenameWithoutExtension(filename);
    String outputDir = options['output'] ?? '';
    String beforeFile = pathlib.join(outputDir, '$name.before.txt');
    String afterFile = pathlib.join(outputDir, '$name.after.txt');
    NameSystem names = new NameSystem();
    StringBuffer before = new StringBuffer();
    new Printer(before, syntheticNames: names).writeComponentFile(component);
    new File(beforeFile).writeAsStringSync('$before');
    new TreeShaker(coreTypes, hierarchy, component, legacyMode: legacyMode)
        .transform(component);
    StringBuffer after = new StringBuffer();
    new Printer(after, syntheticNames: names).writeComponentFile(component);
    new File(afterFile).writeAsStringSync('$after');
    print('Text written to $beforeFile and $afterFile');
  }
}

String ratio(num x, num total) {
  return '$x / $total (${percent(x, total)})';
}

String percent(num x, num total) {
  return total == 0 ? '0%' : ((100 * x / total).toStringAsFixed(0) + '%');
}
