#!/usr/bin/env vpython
#
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# 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.')
  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())
