// 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 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);
  CoreTypes coreTypes = new CoreTypes(program);
  ClassHierarchy hierarchy = new ClassHierarchy(program);
  TreeShaker shaker =
      new TreeShaker(coreTypes, hierarchy, 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(coreTypes, hierarchy, 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) + '%');
}
