#!/usr/bin/env vpython3
#
# Copyright 2012 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Utility script to install APKs from the command line quickly."""

import argparse
import glob
import logging
import os
import sys

import devil_chromium
from devil.android import apk_helper
from devil.android import device_denylist
from devil.android import device_errors
from devil.android import device_utils
from devil.utils import run_tests_helper
from pylib import constants


def main():
  parser = argparse.ArgumentParser()

  apk_group = parser.add_mutually_exclusive_group(required=True)
  apk_group.add_argument('--apk', dest='apk_name',
                         help='DEPRECATED The name of the apk containing the'
                              ' application (with the .apk extension).')
  apk_group.add_argument('apk_path', nargs='?',
                         help='The path to the APK to install.')

  # TODO(jbudorick): Remove once no clients pass --apk_package
  parser.add_argument('--apk_package', help='DEPRECATED unused')
  parser.add_argument('--split',
                      action='append',
                      dest='splits',
                      help='A glob matching the apk splits. '
                           'Can be specified multiple times.')
  parser.add_argument('--keep_data',
                      action='store_true',
                      default=False,
                      help='Keep the package data when installing '
                           'the application.')
  parser.add_argument('--debug', action='store_const', const='Debug',
                      dest='build_type',
                      default=os.environ.get('BUILDTYPE', 'Debug'),
                      help='If set, run test suites under out/Debug. '
                           'Default is env var BUILDTYPE or Debug')
  parser.add_argument('--release', action='store_const', const='Release',
                      dest='build_type',
                      help='If set, run test suites under out/Release. '
                           'Default is env var BUILDTYPE or Debug.')
  parser.add_argument('-d', '--device', dest='devices', action='append',
                      default=[],
                      help='Target device for apk to install on. Enter multiple'
                           ' times for multiple devices.')
  parser.add_argument('--adb-path', type=os.path.abspath,
                      help='Absolute path to the adb binary to use.')
  parser.add_argument('--denylist-file', help='Device denylist JSON file.')
  parser.add_argument('-v',
                      '--verbose',
                      action='count',
                      help='Enable verbose logging.',
                      default=0)
  parser.add_argument('--downgrade', action='store_true',
                      help='If set, allows downgrading of apk.')
  parser.add_argument('--timeout', type=int,
                      default=device_utils.DeviceUtils.INSTALL_DEFAULT_TIMEOUT,
                      help='Seconds to wait for APK installation. '
                           '(default: %(default)s)')

  args = parser.parse_args()

  run_tests_helper.SetLogLevel(args.verbose)
  constants.SetBuildType(args.build_type)

  devil_chromium.Initialize(
      output_directory=constants.GetOutDirectory(),
      adb_path=args.adb_path)

  apk = args.apk_path or args.apk_name
  if not apk.endswith('.apk'):
    apk += '.apk'
  if not os.path.exists(apk):
    apk = os.path.join(constants.GetOutDirectory(), 'apks', apk)
    if not os.path.exists(apk):
      parser.error('%s not found.' % apk)

  if args.splits:
    splits = []
    base_apk_package = apk_helper.ApkHelper(apk).GetPackageName()
    for split_glob in args.splits:
      apks = [f for f in glob.glob(split_glob) if f.endswith('.apk')]
      if not apks:
        logging.warning('No apks matched for %s.', split_glob)
      for f in apks:
        helper = apk_helper.ApkHelper(f)
        if (helper.GetPackageName() == base_apk_package
            and helper.GetSplitName()):
          splits.append(f)

  denylist = (device_denylist.Denylist(args.denylist_file)
              if args.denylist_file else None)
  devices = device_utils.DeviceUtils.HealthyDevices(denylist=denylist,
                                                    device_arg=args.devices)

  def denylisting_install(device):
    try:
      if args.splits:
        device.InstallSplitApk(apk, splits, reinstall=args.keep_data,
                               allow_downgrade=args.downgrade)
      else:
        device.Install(apk, reinstall=args.keep_data,
                       allow_downgrade=args.downgrade,
                       timeout=args.timeout)
    except (device_errors.CommandFailedError,
            device_errors.DeviceUnreachableError):
      logging.exception('Failed to install %s', apk)
      if denylist:
        denylist.Extend([str(device)], reason='install_failure')
        logging.warning('Denylisting %s', str(device))
    except device_errors.CommandTimeoutError:
      logging.exception('Timed out while installing %s', apk)
      if denylist:
        denylist.Extend([str(device)], reason='install_timeout')
        logging.warning('Denylisting %s', str(device))

  device_utils.DeviceUtils.parallel(devices).pMap(denylisting_install)


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