// 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('strong', help: 'Run the tree shaker in strong 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 strong = options['strong'];

  Component component = loadComponentFromBinary(filename);
  CoreTypes coreTypes = new CoreTypes(component);
  ClassHierarchy hierarchy = new ClassHierarchy(component);
  TreeShaker shaker =
      new TreeShaker(coreTypes, hierarchy, component, strongMode: strong);
  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, strongMode: strong)
        .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) + '%');
}
