// 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/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 program 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'];

  Program program = loadProgramFromBinary(filename);
  TreeShaker shaker = new TreeShaker(program, 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 program.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).writeProgramFile(program);
    new File(beforeFile).writeAsStringSync('$before');
    new TreeShaker(program, strongMode: strong).transform(program);
    StringBuffer after = new StringBuffer();
    new Printer(after, syntheticNames: names).writeProgramFile(program);
    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) + '%');
}
