#!/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 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')
  (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):
  print 'Signing (ignore the warnings)'
  cmd = ['zip', '-d', unsigned_apk, 'META-INF/*']
  utils.PrintCmd(cmd)
  subprocess.call(cmd)
  signed_apk = os.path.join(temp, 'unaligned.apk')
  cmd = [
    'jarsigner',
    '-sigalg', 'SHA1withRSA',
    '-digestalg', 'SHA1',
    '-keystore', keystore,
    '-storepass', 'android',
    '-signedjar', signed_apk,
    unsigned_apk,
    'androiddebugkey'
  ]
  utils.PrintCmd(cmd)
  subprocess.check_call(cmd)
  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)
    if options.install:
      cmd = ['adb', 'install', '-t', '-r', '-d', options.out]
      utils.PrintCmd(cmd)
      subprocess.check_call(cmd)
  return 0

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