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

import utils
import zip_utils

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

def parse_options():
  parser = optparse.OptionParser(usage=USAGE)
  parser.add_option('--keystore',
                    help='keystore file (default ~/.android/app.keystore)',
                    default='~/.android/app.keystore')
  parser.add_option('--sign',
                    help='Sign the passed in apk.',
                    default=False,
                    action='store_true')
  parser.add_option('--use_apksigner',
                    help='Use apksigner to sign.',
                    default=False,
                    action='store_true')
  parser.add_option('--output',
                    help='Where to put the signed apk.)',
                    default=None)

  (options, args) = parser.parse_args()
  if len(args) != 1:
    parser.error('Expected <apk> argument, got: ' + ' '.join(args))
  apk = args[0]
  return (options, apk)

def add_baseline_profile_to_apk(
    apk, baseline_profile, baseline_profile_metadata, tmp_dir):
  if baseline_profile is None:
    return apk
  ts = time.time_ns()
  dest_apk = os.path.join(tmp_dir, 'app-%s.apk' % ts)
  dest_apk_aligned = os.path.join(tmp_dir, 'app-aligned-%s.apk' % ts)
  dest_apk_signed = os.path.join(tmp_dir, 'app-signed-%s.apk' % ts)
  shutil.copy2(apk, dest_apk)
  zip_utils.remove_files_from_zip(
      ['assets/dexopt/baseline.prof', 'assets/dexopt/baseline.profm'], dest_apk)
  zip_utils.add_file_to_zip(
      baseline_profile, 'assets/dexopt/baseline.prof', dest_apk)
  if baseline_profile_metadata is not None:
    zip_utils.add_file_to_zip(
        baseline_profile_metadata, 'assets/dexopt/baseline.profm', dest_apk)
  align(dest_apk, dest_apk_aligned)
  sign_with_apksigner(dest_apk_aligned, dest_apk_signed)
  return dest_apk_signed

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

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

def get_min_api(apk):
  aapt = os.path.join(utils.getAndroidBuildTools(), 'aapt')
  cmd = [aapt, 'dump', 'badging', apk]
  stdout = subprocess.check_output(cmd).decode('utf-8').strip()
  for line in stdout.splitlines():
    if line.startswith('sdkVersion:\''):
      return int(line[len('sdkVersion:\''): -1])
  raise ValueError('Unexpected stdout: %s' % stdout)

def sign(unsigned_apk, signed_apk, keystore, quiet=False, logging=True):
  utils.Print('Signing (ignore the warnings)', quiet=quiet)
  cmd = ['zip', '-d', unsigned_apk, 'META-INF/*']
  utils.RunCmd(cmd, quiet=quiet, logging=logging, fail=False)
  cmd = [
    'jarsigner',
    '-sigalg', 'SHA1withRSA',
    '-digestalg', 'SHA1',
    '-keystore', keystore,
    '-storepass', 'android',
    '-signedjar', signed_apk,
    unsigned_apk,
    'androiddebugkey'
  ]
  utils.RunCmd(cmd, quiet=quiet)

def sign_with_apksigner(
    unsigned_apk, signed_apk, keystore=None, password='android', quiet=False,
    logging=True):
  cmd = [
    os.path.join(utils.getAndroidBuildTools(), 'apksigner'),
    'sign',
    '-v',
    '--ks', keystore or default_keystore(),
    '--ks-pass', 'pass:' + password,
    '--min-sdk-version', '19',
    '--out', signed_apk,
    '--v2-signing-enabled',
    unsigned_apk
  ]
  utils.RunCmd(cmd, quiet=quiet, logging=logging)
  return signed_apk

def main():
  (options, apk) = parse_options()
  if options.sign:
    if not options.output:
      print('When signing you must specify an output apk')
      return 1
    if not options.keystore:
      print('When signing you must specify a keystore')
      return 1
    if options.use_apksigner:
      sign_with_apksigner(apk, options.output, options.keystore)
    else:
      sign(apk, options.output, options.keystore)
  return 0

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