#!/usr/bin/env python
# Copyright (c) 2017, 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 apk_utils
import glob
import optparse
import os
import shutil
import sys
import utils

USAGE = 'usage: %prog [options] <apk>'

def parse_options():
  parser = optparse.OptionParser(usage=USAGE)
  parser.add_option('--dex',
                    help=('directory with dex files to use instead of those in '
                        + 'the apk'),
                    default=None)
  parser.add_option('--resources',
                    help=('pattern that matches resources to use instead of '
                        + 'those in the apk'),
                    default=None)
  parser.add_option('--out',
                    help='output file (default ./$(basename <apk>))',
                    default=None)
  parser.add_option('--keystore',
                    help='keystore file (default ~/.android/app.keystore)',
                    default=None)
  parser.add_option('--install',
                    help='install the generated apk with adb options -t -r -d',
                    default=False,
                    action='store_true')
  parser.add_option('--adb-options',
                    help='additional adb options when running adb',
                    default=None)
  parser.add_option('--quiet',
                    help='disable verbose logging',
                    default=False)
  (options, args) = parser.parse_args()
  if len(args) != 1:
    parser.error('Expected <apk> argument, got: ' + ' '.join(args))
  apk = args[0]
  return (options, apk)

def findKeystore():
  return os.path.join(os.getenv('HOME'), '.android', 'app.keystore')

def repack(apk, processed_out, resources, temp, quiet, logging):
  processed_apk = os.path.join(temp, 'processed.apk')
  shutil.copyfile(apk, processed_apk)
  if not processed_out:
    utils.Print('Using original APK as is', quiet=quiet)
    return processed_apk
  utils.Print(
      'Repacking APK with dex files from {}'.format(processed_apk), quiet=quiet)

  # Delete original dex files in APK.
  with utils.ChangedWorkingDirectory(temp, quiet=quiet):
    cmd = ['zip', '-d', 'processed.apk', '*.dex']
    utils.RunCmd(cmd, quiet=quiet, logging=logging)

  # Unzip the jar or zip file into `temp`.
  if processed_out.endswith('.zip') or processed_out.endswith('.jar'):
    cmd = ['unzip', processed_out, '-d', temp]
    if quiet:
      cmd.insert(1, '-q')
    utils.RunCmd(cmd, quiet=quiet, logging=logging)
    processed_out = temp

  # Insert the new dex and resource files from `processed_out` into the APK.
  with utils.ChangedWorkingDirectory(processed_out, quiet=quiet):
    dex_files = glob.glob('*.dex')
    resource_files = glob.glob(resources) if resources else []
    cmd = ['zip', '-u', '-9', processed_apk] + dex_files + resource_files
    utils.RunCmd(cmd, quiet=quiet, logging=logging)
  return processed_apk

def sign(unsigned_apk, keystore, temp, quiet, logging):
  signed_apk = os.path.join(temp, 'unaligned.apk')
  apk_utils.sign_with_apksigner(
      unsigned_apk, signed_apk, keystore, quiet=quiet, logging=logging)
  return signed_apk

def align(signed_apk, temp, quiet, logging):
  utils.Print('Aligning', quiet=quiet)
  aligned_apk = os.path.join(temp, 'aligned.apk')
  zipalign_path = (
      'zipalign' if 'build_tools' in os.environ.get('PATH')
      else os.path.join(utils.getAndroidBuildTools(), 'zipalign'))
  cmd = [
    zipalign_path,
    '-f',
    '4',
    signed_apk,
    aligned_apk
  ]
  utils.RunCmd(cmd, quiet=quiet, logging=logging)
  return signed_apk

def masseur(
    apk, dex=None, resources=None, out=None, adb_options=None, keystore=None,
    install=False, quiet=False, logging=True):
  if not out:
    out = os.path.basename(apk)
  if not keystore:
    keystore = findKeystore()
  with utils.TempDir() as temp:
    processed_apk = None
    if dex:
      processed_apk = repack(apk, dex, resources, temp, quiet, logging)
    else:
      utils.Print(
          'Signing original APK without modifying dex files', quiet=quiet)
      processed_apk = os.path.join(temp, 'processed.apk')
      shutil.copyfile(apk, processed_apk)
    signed_apk = sign(
        processed_apk, keystore, temp, quiet=quiet, logging=logging)
    aligned_apk = align(signed_apk, temp, quiet=quiet, logging=logging)
    utils.Print('Writing result to {}'.format(out), quiet=quiet)
    shutil.copyfile(aligned_apk, out)
    if install:
      adb_cmd = ['adb']
      if adb_options:
        adb_cmd.extend(
            [option for option in adb_options.split(' ') if option])
      adb_cmd.extend(['install', '-t', '-r', '-d', out]);
      utils.RunCmd(adb_cmd, quiet=quiet, logging=logging)

def main():
  (options, apk) = parse_options()
  masseur(apk, **vars(options))
  return 0

if __name__ == '__main__':
  sys.exit(main())
