#!/usr/bin/env python3
# Copyright (c) 2022, the R8 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.

import adb_utils
import profile_utils

import argparse
import os
import sys
import time

class Device:

  def __init__(self, device_id, device_pin):
    self.device_id = device_id
    self.device_pin = device_pin

def extend_startup_descriptors(startup_descriptors, iteration, device, options):
  (logcat, profile, profile_classes_and_methods) = \
      generate_startup_profile(device, options)
  if options.logcat:
    write_tmp_logcat(logcat, iteration, options)
    current_startup_descriptors = get_r8_startup_descriptors_from_logcat(
        logcat, options)
  else:
    write_tmp_profile(profile, iteration, options)
    write_tmp_profile_classes_and_methods(
        profile_classes_and_methods, iteration, options)
    current_startup_descriptors = \
        profile_utils.transform_art_profile_to_r8_startup_list(
            profile_classes_and_methods)
  write_tmp_startup_descriptors(current_startup_descriptors, iteration, options)
  new_startup_descriptors = add_r8_startup_descriptors(
      startup_descriptors, current_startup_descriptors)
  number_of_new_startup_descriptors = \
      len(new_startup_descriptors) - len(startup_descriptors)
  if options.out is not None:
    print(
        'Found %i new startup descriptors in iteration %i'
            % (number_of_new_startup_descriptors, iteration + 1))
  return new_startup_descriptors

def generate_startup_profile(device, options):
  logcat = None
  profile = None
  profile_classes_and_methods = None
  if options.use_existing_profile:
    # Verify presence of profile.
    adb_utils.check_app_has_profile_data(options.app_id, device.device_id)
    profile = adb_utils.get_profile_data(options.app_id, device.device_id)
    profile_classes_and_methods = \
        adb_utils.get_classes_and_methods_from_app_profile(
            options.app_id, device.device_id)
  else:
    # Unlock device.
    tear_down_options = adb_utils.prepare_for_interaction_with_device(
        device.device_id, device.device_pin)

    logcat_process = None
    if options.logcat:
      # Clear logcat and start capturing logcat.
      adb_utils.clear_logcat(device.device_id)
      logcat_process = adb_utils.start_logcat(
          device.device_id, format='tag', filter='r8:I ActivityTaskManager:I *:S')
    else:
      # Clear existing profile data.
      adb_utils.clear_profile_data(options.app_id, device.device_id)

    # Launch activity to generate startup profile on device.
    adb_utils.launch_activity(
        options.app_id, options.main_activity, device.device_id)

    # Wait for activity startup.
    time.sleep(options.startup_duration)

    if options.logcat:
      # Get startup descriptors from logcat.
      logcat = adb_utils.stop_logcat(logcat_process)
    else:
      # Capture startup profile.
      adb_utils.capture_app_profile_data(options.app_id, device.device_id)
      profile = adb_utils.get_profile_data(options.app_id, device.device_id)
      profile_classes_and_methods = \
          adb_utils.get_classes_and_methods_from_app_profile(
              options.app_id, device.device_id)

    # Shutdown app.
    adb_utils.stop_app(options.app_id, device.device_id)
    adb_utils.teardown_after_interaction_with_device(
        tear_down_options, device.device_id)

  return (logcat, profile, profile_classes_and_methods)

def get_r8_startup_descriptors_from_logcat(logcat, options):
  post_startup = False
  startup_descriptors = {}
  for line in logcat:
    line_elements = parse_logcat_line(line)
    if line_elements is None:
      continue
    (priority, tag, message) = line_elements
    if tag == 'ActivityTaskManager':
      if message.startswith('START') \
          or message.startswith('Activity pause timeout for') \
          or message.startswith('Activity top resumed state loss timeout for') \
          or message.startswith('Force removing') \
          or message.startswith(
              'Launch timeout has expired, giving up wake lock!'):
        continue
      elif message.startswith('Displayed %s/' % options.app_id):
        print('Entering post startup: %s' % message)
        post_startup = True
        continue
    elif tag == 'r8':
      if is_startup_descriptor(message):
        startup_descriptors[message] = {
          'conditional_startup': False,
          'post_startup': post_startup
        }
        continue
    # Reaching here means we didn't expect this line.
    report_unrecognized_logcat_line(line)
  return startup_descriptors

def is_startup_descriptor(string):
  # The descriptor should start with the holder (possibly prefixed with 'S').
  if not any(string.startswith('%sL' % flags) for flags in ['', 'S']):
    return False
  # The descriptor should end with ';', a primitive type, or void.
  if not string.endswith(';') \
      and not any(string.endswith(c) for c in get_primitive_descriptors()) \
      and not string.endswith('V'):
    return False
  return True

def get_primitive_descriptors():
  return ['Z', 'B', 'S', 'C', 'I', 'F', 'J', 'D']

def parse_logcat_line(line):
  if line == '--------- beginning of kernel':
    return None
  if line == '--------- beginning of main':
    return None
  if line == '--------- beginning of system':
    return None

  priority = None
  tag = None

  try:
    priority_end = line.index('/')
    priority = line[0:priority_end]
    line = line[priority_end + 1:]
  except ValueError:
    return report_unrecognized_logcat_line(line)

  try:
    tag_end = line.index(':')
    tag = line[0:tag_end].strip()
    line = line[tag_end + 1 :]
  except ValueError:
    return report_unrecognized_logcat_line(line)

  message = line.strip()
  return (priority, tag, message)

def report_unrecognized_logcat_line(line):
  print('Unrecognized line in logcat: %s' % line)

def add_r8_startup_descriptors(old_startup_descriptors, startup_descriptors_to_add):
  new_startup_descriptors = {}
  if len(old_startup_descriptors) == 0:
    for startup_descriptor, flags in startup_descriptors_to_add.items():
      new_startup_descriptors[startup_descriptor] = flags.copy()
  else:
    # Merge the new startup descriptors with the old descriptors in a way so
    # that new startup descriptors are added next to the startup descriptors
    # they are close to in the newly generated list of startup descriptors.
    startup_descriptors_to_add_after_key = {}
    startup_descriptors_to_add_in_the_end = {}
    closest_seen_startup_descriptor = None
    for startup_descriptor, flags in startup_descriptors_to_add.items():
      if startup_descriptor in old_startup_descriptors:
        closest_seen_startup_descriptor = startup_descriptor
      else:
        if closest_seen_startup_descriptor is None:
          # Insert this new startup descriptor in the end of the result.
          startup_descriptors_to_add_in_the_end[startup_descriptor] = flags
        else:
          # Record that this should be inserted after
          # closest_seen_startup_descriptor.
          pending_startup_descriptors = \
              startup_descriptors_to_add_after_key.setdefault(
                  closest_seen_startup_descriptor, {})
          pending_startup_descriptors[startup_descriptor] = flags
    for startup_descriptor, flags in old_startup_descriptors.items():
      # Merge flags if this also exists in startup_descriptors_to_add.
      if startup_descriptor in startup_descriptors_to_add:
        merged_flags = flags.copy()
        other_flags = startup_descriptors_to_add[startup_descriptor]
        assert not other_flags['conditional_startup']
        if other_flags['post_startup']:
          merged_flags['post_startup'] = True
        new_startup_descriptors[startup_descriptor] = merged_flags
      else:
        new_startup_descriptors[startup_descriptor] = flags.copy()
      # Flush startup descriptors that followed this item in the new trace.
      if startup_descriptor in startup_descriptors_to_add_after_key:
        pending_startup_descriptors = \
            startup_descriptors_to_add_after_key[startup_descriptor]
        for pending_startup_descriptor, pending_flags \
            in pending_startup_descriptors.items():
          new_startup_descriptors[pending_startup_descriptor] = \
              pending_flags.copy()
    # Insert remaining new startup descriptors in the end.
    for startup_descriptor, flags \
        in startup_descriptors_to_add_in_the_end.items():
      assert startup_descriptor not in new_startup_descriptors
      new_startup_descriptors[startup_descriptor] = flags.copy()
  return new_startup_descriptors

def write_tmp_binary_artifact(artifact, iteration, options, name):
  if not options.tmp_dir:
    return
  out_dir = os.path.join(options.tmp_dir, str(iteration))
  os.makedirs(out_dir, exist_ok=True)
  path = os.path.join(out_dir, name)
  with open(path, 'wb') as f:
    f.write(artifact)

def write_tmp_textual_artifact(artifact, iteration, options, name, item_to_string=None):
  if not options.tmp_dir:
    return
  out_dir = os.path.join(options.tmp_dir, str(iteration))
  os.makedirs(out_dir, exist_ok=True)
  path = os.path.join(out_dir, name)
  with open(path, 'w') as f:
    for item in artifact:
      f.write(item if item_to_string is None else item_to_string(item))
      f.write('\n')

def write_tmp_logcat(logcat, iteration, options):
  write_tmp_textual_artifact(logcat, iteration, options, 'logcat.txt')

def write_tmp_profile(profile, iteration, options):
  write_tmp_binary_artifact(profile, iteration, options, 'primary.prof')

def write_tmp_profile_classes_and_methods(
    profile_classes_and_methods, iteration, options):
  def item_to_string(item):
    (descriptor, flags) = item
    return '%s%s%s%s' % (
        'H' if flags.get('hot') else '',
        'S' if flags.get('startup') else '',
        'P' if flags.get('post_startup') else '',
        descriptor)
  write_tmp_textual_artifact(
      profile_classes_and_methods.items(),
      iteration,
      options,
      'profile.txt',
      item_to_string)

def write_tmp_startup_descriptors(startup_descriptors, iteration, options):
  lines = [
      startup_descriptor_to_string(startup_descriptor, flags)
      for startup_descriptor, flags in startup_descriptors.items()]
  write_tmp_textual_artifact(
      lines, iteration, options, 'startup-descriptors.txt')

def startup_descriptor_to_string(startup_descriptor, flags):
  result = ''
  if flags['conditional_startup']:
    pass # result += 'C'
  if flags['post_startup']:
    pass # result += 'P'
  result += startup_descriptor
  return result

def should_include_startup_descriptor(descriptor, flags, options):
  if flags.get('conditional_startup') \
      and not options.include_conditional_startup:
    return False
  if flags.get('post_startup') \
      and not flags.get('startup') \
      and not options.include_post_startup:
    return False
  return True

def parse_options(argv):
  result = argparse.ArgumentParser(
      description='Generate a perfetto trace file.')
  result.add_argument('--apk',
                      help='Path to the .apk')
  result.add_argument('--apks',
                      help='Path to the .apks')
  result.add_argument('--app-id',
                      help='The application ID of interest',
                      required=True)
  result.add_argument('--bundle',
                      help='Path to the .aab')
  result.add_argument('--device-id',
                      help='Device id (e.g., emulator-5554).',
                      action='append')
  result.add_argument('--device-pin',
                      help='Device pin code (e.g., 1234)',
                      action='append')
  result.add_argument('--logcat',
                      action='store_true',
                      default=False)
  result.add_argument('--include-conditional-startup',
                      help='Include conditional startup classes and methods in '
                           'the R8 startup descriptors',
                      action='store_true',
                      default=False)
  result.add_argument('--include-post-startup',
                      help='Include post startup classes and methods in the R8 '
                           'startup descriptors',
                      action='store_true',
                      default=False)
  result.add_argument('--iterations',
                      help='Number of profiles to generate',
                      default=1,
                      type=int)
  result.add_argument('--main-activity',
                      help='Main activity class name')
  result.add_argument('--out',
                      help='File where to store startup descriptors (defaults '
                           'to stdout)')
  result.add_argument('--startup-duration',
                      help='Duration in seconds before shutting down app',
                      default=15,
                      type=int)
  result.add_argument('--tmp-dir',
                      help='Directory where to store intermediate artifacts'
                            ' (by default these are not emitted)')
  result.add_argument('--until-stable',
                      help='Repeat profile generation until no new startup '
                           'descriptors are found',
                      action='store_true',
                      default=False)
  result.add_argument('--until-stable-iterations',
                      help='Number of times that profile generation must must '
                           'not find new startup descriptors before exiting',
                      default=1,
                      type=int)
  result.add_argument('--use-existing-profile',
                      help='Do not launch app to generate startup profile',
                      action='store_true',
                      default=False)
  options, args = result.parse_known_args(argv)

  # Read the device pins.
  device_pins = options.device_pin or []
  del options.device_pin

  # Convert the device ids and pins into a list of devices.
  options.devices = []
  if options.device_id is None:
    # Assume a single device is attached.
    options.devices.append(
        Device(None, device_pins[0] if len(device_pins) > 0 else None))
  else:
    for i in range(len(options.device_id)):
      device_id = options.device_id[i]
      device_pin = device_pins[i] if i < len(device_pins) else None
      options.devices.append(Device(device_id, device_pin))
  del options.device_id

  paths = [
      path for path in [options.apk, options.apks, options.bundle]
      if path is not None]
  assert len(paths) <= 1, 'Expected at most one .apk, .apks, or .aab file.'
  assert options.main_activity is not None or options.use_existing_profile, \
      'Argument --main-activity is required except when running with ' \
      '--use-existing-profile.'

  return options, args

def run_on_device(device, options, startup_descriptors):
  adb_utils.root(device.device_id)
  if options.apk:
    adb_utils.uninstall(options.app_id, device.device_id)
    adb_utils.install(options.apk, device.device_id)
  elif options.apks:
    adb_utils.uninstall(options.app_id, device.device_id)
    adb_utils.install_apks(options.apks, device.device_id)
  elif options.bundle:
    adb_utils.uninstall(options.app_id, device.device_id)
    adb_utils.install_bundle(options.bundle, device.device_id)
  if options.until_stable:
    iteration = 0
    stable_iterations = 0
    while True:
      old_startup_descriptors = startup_descriptors
      startup_descriptors = extend_startup_descriptors(
          old_startup_descriptors, iteration, device, options)
      diff = len(startup_descriptors) - len(old_startup_descriptors)
      if diff == 0:
        stable_iterations = stable_iterations + 1
        if stable_iterations == options.until_stable_iterations:
          break
      else:
        stable_iterations = 0
      iteration = iteration + 1
  else:
    for iteration in range(options.iterations):
      startup_descriptors = extend_startup_descriptors(
          startup_descriptors, iteration, device, options)
  return startup_descriptors

def main(argv):
  (options, args) = parse_options(argv)
  startup_descriptors = {}
  for device in options.devices:
    startup_descriptors = run_on_device(device, options, startup_descriptors)
  if options.out is not None:
    with open(options.out, 'w') as f:
      for startup_descriptor, flags in startup_descriptors.items():
        if should_include_startup_descriptor(startup_descriptor, flags, options):
          f.write(startup_descriptor_to_string(startup_descriptor, flags))
          f.write('\n')
  else:
    for startup_descriptor, flags in startup_descriptors.items():
      if should_include_startup_descriptor(startup_descriptor, flags, options):
        print(startup_descriptor_to_string(startup_descriptor, flags))

if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
