#!/usr/bin/env python3
# Copyright (c) 2023, 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 os
import shutil
import subprocess
import sys

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

import apk_masseur
import apk_utils
import extractmarker
import toolhelper
import utils
import zip_utils

def parse_options(argv):
  result = argparse.ArgumentParser(
      description='Instrument the dex files of a given apk to print what is '
                  'executed.')
  result.add_argument('--apk',
                      help='Path to the .apk',
                      required=True)
  result.add_argument('--dex-files',
                      action='append',
                      help='Name of dex files to instrument')
  result.add_argument('--discard',
                      action='append',
                      help='Name of dex files to discard')
  result.add_argument('--out',
                      help='Destination of resulting apk',
                      required=True)
  options, args = result.parse_known_args(argv)
  return options, args

def add_instrumented_dex(dex_file, instrumented_dex_index, instrumented_dir):
  dex_name = get_dex_name(instrumented_dex_index)
  destination = os.path.join(instrumented_dir, dex_name)
  shutil.move(dex_file, destination)

def get_dex_name(dex_index):
  assert dex_index > 0
  return 'classes.dex' if dex_index == 1 else ('classes%s.dex' % dex_index)

def instrument_dex_file(dex_file, include_instrumentation_server, options, tmp_dir):
  d8_cmd = [
      'java',
      '-cp', utils.R8_JAR,
      '-Dcom.android.tools.r8.startup.instrumentation.instrument=1',
      '-Dcom.android.tools.r8.startup.instrumentation.instrumentationtag=R8']
  if not include_instrumentation_server:
    # We avoid injecting the InstrumentationServer by specifying it should only
    # be added if foo.bar.Baz is in the program.
    d8_cmd.append(
        '-Dcom.android.tools.r8.startup.instrumentation.instrumentationserversyntheticcontext=foo.bar.Baz')
  d8_cmd.extend([
      'com.android.tools.r8.D8',
      '--min-api', str(apk_utils.get_min_api(options.apk)),
      '--output', tmp_dir,
      '--release',
      dex_file])
  subprocess.check_call(d8_cmd)
  instrumented_dex_files = []
  instrumented_dex_index = 1
  while True:
    instrumented_dex_name = get_dex_name(instrumented_dex_index)
    instrumented_dex_file = os.path.join(tmp_dir, instrumented_dex_name)
    if not os.path.exists(instrumented_dex_file):
      break
    instrumented_dex_files.append(instrumented_dex_file)
    instrumented_dex_index = instrumented_dex_index + 1
  assert len(instrumented_dex_files) > 0
  return instrumented_dex_files

def should_discard_dex_file(dex_name, options):
  return options.discard is not None and dex_name in options.discard

def should_instrument_dex_file(dex_name, options):
  return options.dex_files is not None and dex_name in options.dex_files

def main(argv):
  options, args = parse_options(argv)
  with utils.TempDir() as tmp_dir:
    # Extract the dex files of the apk.
    uninstrumented_dir = os.path.join(tmp_dir, 'uninstrumented')
    os.mkdir(uninstrumented_dir)

    dex_predicate = \
        lambda name : name.startswith('classes') and name.endswith('.dex')
    zip_utils.extract_all_that_matches(
        options.apk, uninstrumented_dir, dex_predicate)

    # Instrument each dex one by one.
    instrumented_dir = os.path.join(tmp_dir, 'instrumented')
    os.mkdir(instrumented_dir)

    include_instrumentation_server = True
    instrumented_dex_index = 1
    uninstrumented_dex_index = 1
    while True:
      dex_name = get_dex_name(uninstrumented_dex_index)
      dex_file = os.path.join(uninstrumented_dir, dex_name)
      if not os.path.exists(dex_file):
        break
      if not should_discard_dex_file(dex_name, options):
        if should_instrument_dex_file(dex_name, options):
          with utils.TempDir() as tmp_instrumentation_dir:
            instrumented_dex_files = \
                instrument_dex_file(
                    dex_file,
                    include_instrumentation_server,
                    options,
                    tmp_instrumentation_dir)
            for instrumented_dex_file in instrumented_dex_files:
              add_instrumented_dex(
                  instrumented_dex_file, instrumented_dex_index, instrumented_dir)
              instrumented_dex_index = instrumented_dex_index + 1
            include_instrumentation_server = False
        else:
          add_instrumented_dex(dex_file, instrumented_dex_index, instrumented_dir)
          instrumented_dex_index = instrumented_dex_index + 1
      uninstrumented_dex_index = uninstrumented_dex_index + 1

    assert instrumented_dex_index > 1

    # Masseur APK.
    apk_masseur.masseur(options.apk, dex=instrumented_dir, out=options.out)

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