#! /usr/bin/env python
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from __future__ import print_function

import argparse
import os
import re
import zipfile

from pylib.dex import dex_parser


class DexStatsCollector(object):
  """Tracks count of method/field/string/type as well as unique methods."""

  def __init__(self):
    # Signatures of all methods from all seen dex files.
    self._unique_methods = set()
    # Map of label -> { metric -> count }.
    self._counts_by_label = {}

  def _CollectFromDexfile(self, label, dexfile):
    assert label not in self._counts_by_label, 'exists: ' + label
    self._counts_by_label[label] = {
        'fields': dexfile.header.field_ids_size,
        'methods': dexfile.header.method_ids_size,
        'strings': dexfile.header.string_ids_size,
        'types': dexfile.header.type_ids_size,
    }
    self._unique_methods.update(dexfile.IterMethodSignatureParts())

  def CollectFromZip(self, label, path):
    """Add dex stats from an .apk/.jar/.aab/.zip."""
    with zipfile.ZipFile(path, 'r') as z:
      for subpath in z.namelist():
        if not re.match(r'.*classes\d*\.dex$', subpath):
          continue
        dexfile = dex_parser.DexFile(bytearray(z.read(subpath)))
        self._CollectFromDexfile('{}!{}'.format(label, subpath), dexfile)

  def CollectFromDex(self, label, path):
    """Add dex stats from a .dex file."""
    with open(path, 'rb') as f:
      dexfile = dex_parser.DexFile(bytearray(f.read()))
    self._CollectFromDexfile(label, dexfile)

  def MergeFrom(self, parent_label, other):
    """Add dex stats from another DexStatsCollector."""
    # pylint: disable=protected-access
    for label, other_counts in other._counts_by_label.items():
      new_label = '{}-{}'.format(parent_label, label)
      self._counts_by_label[new_label] = other_counts.copy()
    self._unique_methods.update(other._unique_methods)
    # pylint: enable=protected-access

  def GetUniqueMethodCount(self):
    """Returns total number of unique methods across encountered dex files."""
    return len(self._unique_methods)

  def GetCountsByLabel(self):
    """Returns dict of label -> {metric -> count}."""
    return self._counts_by_label

  def GetTotalCounts(self):
    """Returns dict of {metric -> count}, where |count| is sum(metric)."""
    ret = {}
    for metric in ('fields', 'methods', 'strings', 'types'):
      ret[metric] = sum(x[metric] for x in self._counts_by_label.values())
    return ret

  def GetDexCacheSize(self, pre_oreo):
    """Returns number of bytes of dirty RAM is consumed from all dex files."""
    # Dex Cache was optimized in Android Oreo:
    # https://source.android.com/devices/tech/dalvik/improvements#dex-cache-removal
    if pre_oreo:
      total = sum(self.GetTotalCounts().values())
    else:
      total = sum(c['methods'] for c in self._counts_by_label.values())
    return total * 4  # 4 bytes per entry.


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('paths', nargs='+')
  args = parser.parse_args()

  collector = DexStatsCollector()
  for path in args.paths:
    if os.path.splitext(path)[1] in ('.zip', '.apk', '.jar', '.aab'):
      collector.CollectFromZip(path, path)
    else:
      collector.CollectFromDex(path, path)

  counts_by_label = collector.GetCountsByLabel()
  for label, counts in sorted(counts_by_label.items()):
    print('{}:'.format(label))
    for metric, count in sorted(counts.items()):
      print('  {}:'.format(metric), count)
    print()

  if len(counts_by_label) > 1:
    print('Totals:')
    for metric, count in sorted(collector.GetTotalCounts().items()):
      print('  {}:'.format(metric), count)
    print()

  print('Unique Methods:', collector.GetUniqueMethodCount())
  print('DexCache (Pre-Oreo):', collector.GetDexCacheSize(pre_oreo=True),
        'bytes of dirty memory')
  print('DexCache (Oreo+):', collector.GetDexCacheSize(pre_oreo=False),
        'bytes of dirty memory')


if __name__ == '__main__':
  main()
