#!/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 argparse
import datetime
import os
import re
import statistics
import sys
import time

try:
  from perfetto.trace_processor import TraceProcessor
except ImportError:
  sys.exit(
      'Unable to analyze perfetto trace without the perfetto library. '
      'Install instructions:\n'
      '    sudo apt install python3-pip\n'
      '    pip3 install perfetto')

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import adb_utils
import apk_utils
import perfetto_utils
import utils

def setup(options):
  # Increase screen off timeout to avoid device screen turns off.
  twenty_four_hours_in_millis = 24 * 60 * 60 * 1000
  previous_screen_off_timeout = adb_utils.get_screen_off_timeout(
      options.device_id)
  adb_utils.set_screen_off_timeout(
      twenty_four_hours_in_millis, options.device_id)

  # Unlock device.
  adb_utils.unlock(options.device_id, options.device_pin)

  teardown_options = {
    'previous_screen_off_timeout': previous_screen_off_timeout
  }
  return teardown_options

def teardown(options, teardown_options):
  # Reset screen off timeout.
  adb_utils.set_screen_off_timeout(
      teardown_options['previous_screen_off_timeout'],
      options.device_id)

def run_all(apk_or_apks, options, tmp_dir):
  # Launch app while collecting information.
  data_total = {}
  for iteration in range(1, options.iterations + 1):
    print('Starting iteration %i' % iteration)
    out_dir = os.path.join(options.out_dir, str(iteration))
    teardown_options = setup_for_run(apk_or_apks, out_dir, options)
    data = run(out_dir, options, tmp_dir)
    teardown_for_run(out_dir, options, teardown_options)
    add_data(data_total, data)
    print('Result:')
    print(data)
    print(compute_data_summary(data_total))
    print('Done')
  print('Average result:')
  data_summary = compute_data_summary(data_total)
  print(data_summary)
  write_data_to_dir(options.out_dir, data_summary)
  if options.out:
    write_data_to_file(options.out, data_summary)

def compute_data_summary(data_total):
  data_summary = {}
  for key, value in data_total.items():
    if not isinstance(value, list):
      data_summary[key] = value
      continue
    data_summary['%s_avg' % key] = round(statistics.mean(value), 1)
    data_summary['%s_med' % key] = statistics.median(value)
    data_summary['%s_min' % key] = min(value)
    data_summary['%s_max' % key] = max(value)
  return data_summary

def setup_for_run(apk_or_apks, out_dir, options):
  adb_utils.root(options.device_id)

  print('Installing')
  adb_utils.uninstall(options.app_id, options.device_id)
  if apk_or_apks['apk']:
    adb_utils.install(apk_or_apks['apk'], options.device_id)
  else:
    assert apk_or_apks['apks']
    adb_utils.install_apks(apk_or_apks['apks'], options.device_id)

  os.makedirs(out_dir, exist_ok=True)

  # AOT compile.
  if options.aot:
    print('AOT compiling')
    if options.baseline_profile:
      adb_utils.clear_profile_data(options.app_id, options.device_id)
      if options.baseline_profile_install == 'adb':
        adb_utils.install_profile_using_adb(
            options.app_id, options.baseline_profile, options.device_id)
      else:
        assert options.baseline_profile_install == 'profileinstaller'
        adb_utils.install_profile_using_profileinstaller(
            options.app_id, options.device_id)
    else:
      adb_utils.force_compilation(options.app_id, options.device_id)

  # Cooldown and then unlock device.
  if options.cooldown > 0:
    print('Cooling down for %i seconds' % options.cooldown)
    assert adb_utils.get_screen_state(options.device_id).is_off()
    time.sleep(options.cooldown)
    teardown_options = adb_utils.prepare_for_interaction_with_device(
        options.device_id, options.device_pin)
  else:
    teardown_options = None

  # Prelaunch for hot startup.
  if options.hot_startup:
    print('Prelaunching')
    adb_utils.launch_activity(
        options.app_id,
        options.main_activity,
        options.device_id,
        wait_for_activity_to_launch=False)
    time.sleep(options.startup_duration)
    adb_utils.navigate_to_home_screen(options.device_id)
    time.sleep(1)

  # Drop caches before run.
  adb_utils.drop_caches(options.device_id)
  return teardown_options

def teardown_for_run(out_dir, options, teardown_options):
  assert adb_utils.get_screen_state(options.device_id).is_on_and_unlocked()

  if options.capture_screen:
    target = os.path.join(out_dir, 'screen.png')
    adb_utils.capture_screen(target, options.device_id)

  if options.cooldown > 0:
    adb_utils.teardown_after_interaction_with_device(
        teardown_options, options.device_id)
    adb_utils.ensure_screen_off(options.device_id)
  else:
    assert teardown_options is None

def run(out_dir, options, tmp_dir):
  assert adb_utils.get_screen_state(options.device_id).is_on_and_unlocked()

  # Start logcat for time to fully drawn.
  logcat_process = None
  if options.fully_drawn_logcat_message:
    adb_utils.clear_logcat(options.device_id)
    logcat_process = adb_utils.start_logcat(
        options.device_id,
        format='time',
        filter='%s ActivityTaskManager:I' % options.fully_drawn_logcat_filter,
        silent=True)

  # Start perfetto trace collector.
  perfetto_process = None
  perfetto_trace_path = None
  if options.perfetto:
    perfetto_process, perfetto_trace_path = perfetto_utils.record_android_trace(
        out_dir, tmp_dir, options.device_id)

  # Launch main activity.
  launch_activity_result = adb_utils.launch_activity(
      options.app_id,
      options.main_activity,
      options.device_id,
      intent_data_uri=options.intent_data_uri,
      wait_for_activity_to_launch=True)

  # Wait for app to be fully drawn.
  logcat = None
  if logcat_process is not None:
    wait_until_fully_drawn(logcat_process, options)
    logcat = adb_utils.stop_logcat(logcat_process)

  # Wait for perfetto trace collector to stop.
  if options.perfetto:
    perfetto_utils.stop_record_android_trace(perfetto_process, out_dir)

  # Get minor and major page faults from app process.
  data = compute_data(
    launch_activity_result, logcat, perfetto_trace_path, options)
  write_data_to_dir(out_dir, data)
  return data

def wait_until_fully_drawn(logcat_process, options):
  print('Waiting until app is fully drawn')
  while True:
    is_fully_drawn = any(
        is_app_fully_drawn_logcat_message(line, options) \
        for line in logcat_process.lines)
    if is_fully_drawn:
      break
    time.sleep(1)
  print('Done')

def compute_time_to_fully_drawn_from_time_to_first_frame(logcat, options):
  displayed_time = None
  fully_drawn_time = None
  for line in logcat:
    if is_app_displayed_logcat_message(line, options):
      displayed_time = get_timestamp_from_logcat_message(line)
    elif is_app_fully_drawn_logcat_message(line, options):
      fully_drawn_time = get_timestamp_from_logcat_message(line)
  assert displayed_time is not None
  assert fully_drawn_time is not None
  assert fully_drawn_time > displayed_time
  return fully_drawn_time - displayed_time

def get_timestamp_from_logcat_message(line):
  time_end_index = len('00-00 00:00:00.000')
  time_format = '%m-%d %H:%M:%S.%f'
  time_str = line[0:time_end_index] + '000'
  time_seconds = datetime.datetime.strptime(time_str, time_format).timestamp()
  return int(time_seconds * 1000)

def is_app_displayed_logcat_message(line, options):
  substring = 'Displayed %s' % adb_utils.get_component_name(
      options.app_id, options.main_activity)
  return substring in line

def is_app_fully_drawn_logcat_message(line, options):
  return re.search(options.fully_drawn_logcat_message, line)

def add_data(data_total, data):
  for key, value in data.items():
    if key == 'app_id':
      assert data_total.get(key, value) == value
      data_total[key] = value
    if key == 'time':
      continue
    if key in data_total:
      if key == 'app_id':
        assert data_total[key] == value
      else:
        existing_value = data_total[key]
        assert isinstance(value, int)
        assert isinstance(existing_value, list)
        existing_value.append(value)
    else:
      assert isinstance(value, int), key
      data_total[key] = [value]

def compute_data(launch_activity_result, logcat, perfetto_trace_path, options):
  minfl, majfl = adb_utils.get_minor_major_page_faults(
      options.app_id, options.device_id)
  meminfo = adb_utils.get_meminfo(options.app_id, options.device_id)
  data = {
    'app_id': options.app_id,
    'time': time.ctime(time.time()),
    'minfl': minfl,
    'majfl': majfl
  }
  data.update(meminfo)
  startup_data = compute_startup_data(
      launch_activity_result, logcat, perfetto_trace_path, options)
  return data | startup_data

def compute_startup_data(
    launch_activity_result, logcat, perfetto_trace_path, options):
  time_to_first_frame = launch_activity_result.get('total_time')
  startup_data = {
    'adb_startup': time_to_first_frame
  }

  # Time to fully drawn.
  if options.fully_drawn_logcat_message:
    startup_data['time_to_fully_drawn'] = \
        compute_time_to_fully_drawn_from_time_to_first_frame(logcat, options) \
            + time_to_first_frame

  # Perfetto stats.
  perfetto_startup_data = {}
  if options.perfetto:
    trace_processor = TraceProcessor(file_path=perfetto_trace_path)

    # Compute time to first frame according to the builtin android_startup
    # metric.
    startup_metric = trace_processor.metric(['android_startup'])
    time_to_first_frame_ms = \
        startup_metric.android_startup.startup[0].to_first_frame.dur_ms
    perfetto_startup_data['perfetto_startup'] = round(time_to_first_frame_ms)

    if not options.hot_startup:
      # Compute time to first and last doFrame event.
      bind_application_slice = perfetto_utils.find_unique_slice_by_name(
          'bindApplication', options, trace_processor)
      activity_start_slice = perfetto_utils.find_unique_slice_by_name(
          'activityStart', options, trace_processor)
      do_frame_slices = perfetto_utils.find_slices_by_name(
          'Choreographer#doFrame', options, trace_processor)
      first_do_frame_slice = next(do_frame_slices)
      *_, last_do_frame_slice = do_frame_slices

      perfetto_startup_data.update({
        'time_to_first_choreographer_do_frame_ms':
            round(perfetto_utils.get_slice_end_since_start(
                first_do_frame_slice, bind_application_slice)),
        'time_to_last_choreographer_do_frame_ms':
            round(perfetto_utils.get_slice_end_since_start(
                last_do_frame_slice, bind_application_slice))
      })

  # Return combined startup data.
  return startup_data | perfetto_startup_data

def write_data_to_dir(out_dir, data):
  data_path = os.path.join(out_dir, 'data.txt')
  write_data_to_file(data_path, data)

def write_data_to_file(out_file, data):
  with open(out_file, 'w') as f:
    for key, value in data.items():
      f.write('%s=%s\n' % (key, str(value)))

def parse_options(argv):
  result = argparse.ArgumentParser(
      description='Generate a perfetto trace file.')
  result.add_argument('--app-id',
                      help='The application ID of interest',
                      required=True)
  result.add_argument('--aot',
                      help='Enable force compilation',
                      default=False,
                      action='store_true')
  result.add_argument('--apk',
                      help='Path to the .apk')
  result.add_argument('--apks',
                      help='Path to the .apks')
  result.add_argument('--bundle',
                      help='Path to the .aab')
  result.add_argument('--capture-screen',
                      help='Take a screenshot after each test',
                      default=False,
                      action='store_true')
  result.add_argument('--cooldown',
                      help='Seconds to wait before running each iteration',
                      default=0,
                      type=int)
  result.add_argument('--device-id',
                      help='Device id (e.g., emulator-5554).')
  result.add_argument('--device-pin',
                      help='Device pin code (e.g., 1234)')
  result.add_argument('--fully-drawn-logcat-filter',
                      help='Logcat filter for the fully drawn message '
                           '(e.g., "tag:I")')
  result.add_argument('--fully-drawn-logcat-message',
                      help='Logcat message that indicates that the app is '
                           'fully drawn (regexp)')
  result.add_argument('--hot-startup',
                      help='Measure hot startup instead of cold startup',
                      default=False,
                      action='store_true')
  result.add_argument('--intent-data-uri',
                      help='Value to use for the -d argument to the intent '
                           'that is used to launch the app')
  result.add_argument('--iterations',
                      help='Number of traces to generate',
                      default=1,
                      type=int)
  result.add_argument('--main-activity',
                      help='Main activity class name',
                      required=True)
  result.add_argument('--no-perfetto',
                      help='Disables perfetto trace generation',
                      action='store_true',
                      default=False)
  result.add_argument('--out',
                      help='File to store result in')
  result.add_argument('--out-dir',
                      help='Directory to store trace files in',
                      required=True)
  result.add_argument('--baseline-profile',
                      help='Baseline profile (.prof) in binary format')
  result.add_argument('--baseline-profile-metadata',
                      help='Baseline profile metadata (.profm) in binary '
                           'format')
  result.add_argument('--baseline-profile-install',
                      help='Whether to install profile using adb or '
                           'profileinstaller',
                      choices=['adb', 'profileinstaller'],
                      default='profileinstaller')
  result.add_argument('--startup-duration',
                      help='Duration in seconds before shutting down app',
                      default=15,
                      type=int)
  options, args = result.parse_known_args(argv)
  setattr(options, 'perfetto', not options.no_perfetto)

  paths = [
      path for path in [options.apk, options.apks, options.bundle]
      if path is not None]
  assert len(paths) == 1, 'Expected exactly one .apk, .apks, or .aab file.'

  # Build .apks file up front to avoid building the bundle upon each install.
  if options.bundle:
    os.makedirs(options.out_dir, exist_ok=True)
    options.apks = os.path.join(options.out_dir, 'Bundle.apks')
    adb_utils.build_apks_from_bundle(
        options.bundle, options.apks, overwrite=True)
    del options.bundle

  # Profile is only used with --aot.
  assert options.aot or not options.baseline_profile

  # Fully drawn logcat filter and message is absent or both present.
  assert (options.fully_drawn_logcat_filter is None) == \
      (options.fully_drawn_logcat_message is None)

  return options, args

def global_setup(options):
  # If there is no cooldown then unlock the screen once. Otherwise we turn off
  # the screen during the cooldown and unlock the screen before each iteration.
  teardown_options = None
  if options.cooldown == 0:
    teardown_options = adb_utils.prepare_for_interaction_with_device(
        options.device_id, options.device_pin)
    assert adb_utils.get_screen_state(options.device_id).is_on()
  else:
    adb_utils.ensure_screen_off(options.device_id)
  return teardown_options

def global_teardown(options, teardown_options):
  if options.cooldown == 0:
    adb_utils.teardown_after_interaction_with_device(
        teardown_options, options.device_id)
  else:
    assert teardown_options is None

def main(argv):
  (options, args) = parse_options(argv)
  with utils.TempDir() as tmp_dir:
    apk_or_apks = { 'apk': options.apk, 'apks': options.apks }
    if options.baseline_profile \
        and options.baseline_profile_install == 'profileinstaller':
      assert not options.apks, 'Unimplemented'
      apk_or_apks['apk'] = apk_utils.add_baseline_profile_to_apk(
          options.apk,
          options.baseline_profile,
          options.baseline_profile_metadata,
          tmp_dir)
    teardown_options = global_setup(options)
    run_all(apk_or_apks, options, tmp_dir)
    global_teardown(options, teardown_options)

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