#!/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 subprocess
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('--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)
  (options, args) = parser.parse_args()
  if len(args) != 1:
    parser.error('Expected <apk> argument, got: ' + ' '.join(args))
  apk = args[0]
  if not options.out:
    options.out = os.path.basename(apk)
  if not options.keystore:
    options.keystore = findKeystore()
  return (options, apk)

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

def repack(processed_out, original_apk, temp):
  processed_apk = os.path.join(temp, 'processed.apk')
  shutil.copyfile(original_apk, processed_apk)
  if not processed_out:
    print 'Using original APK as is'
    return processed_apk
  print 'Repacking APK with dex files from', processed_apk
  with utils.ChangedWorkingDirectory(temp):
    cmd = ['zip', '-d', 'processed.apk', '*.dex']
    utils.PrintCmd(cmd)
    subprocess.check_call(cmd)
  if processed_out.endswith('.zip') or processed_out.endswith('.jar'):
    cmd = ['unzip', processed_out, '-d', temp]
    utils.PrintCmd(cmd)
    subprocess.check_call(cmd)
    processed_out = temp
  with utils.ChangedWorkingDirectory(processed_out):
    dex = glob.glob('*.dex')
    cmd = ['zip', '-u', '-9', processed_apk] + dex
    utils.PrintCmd(cmd)
    subprocess.check_call(cmd)
  return processed_apk

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

def align(signed_apk, temp):
  print 'Aligning'
  aligned_apk = os.path.join(temp, 'aligned.apk')
  cmd = ['zipalign', '-f', '4', signed_apk, aligned_apk]
  print ' '.join(cmd)
  subprocess.check_call(cmd)
  return signed_apk

def main():
  (options, apk) = parse_options()
  with utils.TempDir() as temp:
    processed_apk = None
    if options.dex:
      processed_apk = repack(options.dex, apk, temp)
    else:
      print 'Signing original APK without modifying dex files'
      processed_apk = os.path.join(temp, 'processed.apk')
      shutil.copyfile(apk, processed_apk)
    signed_apk = sign(processed_apk, options.keystore, temp)
    aligned_apk = align(signed_apk, temp)
    print 'Writing result to', options.out
    shutil.copyfile(aligned_apk, options.out)
    adb_cmd = ['adb']
    if options.adb_options:
      adb_cmd.extend(
          [option for option in options.adb_options.split(' ') if option])
    if options.install:
      adb_cmd.extend(['install', '-t', '-r', '-d', options.out]);
      utils.PrintCmd(adb_cmd)
      subprocess.check_call(adb_cmd)
  return 0

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