#!/usr/bin/env python
#
# Copyright 2015 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.

"""Install *_incremental.apk targets as well as their dependent files."""

import argparse
import glob
import logging
import os
import posixpath
import shutil
import sys
import zipfile

sys.path.append(
    os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)))
import devil_chromium
from devil.android import apk_helper
from devil.android import device_utils
from devil.android import device_errors
from devil.android.sdk import version_codes
from devil.utils import reraiser_thread
from pylib import constants
from pylib.utils import run_tests_helper
from pylib.utils import time_profile

prev_sys_path = list(sys.path)
sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir, 'gyp'))
from util import build_utils
sys.path = prev_sys_path


def _DeviceCachePath(device):
  file_name = 'device_cache_%s.json' % device.adb.GetDeviceSerial()
  return os.path.join(constants.GetOutDirectory(), file_name)


def _TransformDexPaths(paths):
  """Given paths like ["/a/b/c", "/a/c/d"], returns ["b.c", "c.d"]."""
  if len(paths) == 1:
    return [os.path.basename(paths[0])]

  prefix_len = len(os.path.commonprefix(paths))
  return [p[prefix_len:].replace(os.sep, '.') for p in paths]


def _Execute(concurrently, *funcs):
  """Calls all functions in |funcs| concurrently or in sequence."""
  timer = time_profile.TimeProfile()
  if concurrently:
    reraiser_thread.RunAsync(funcs)
  else:
    for f in funcs:
      f()
  timer.Stop(log=False)
  return timer


def _GetDeviceIncrementalDir(package):
  """Returns the device path to put incremental files for the given package."""
  return '/data/local/tmp/incremental-app-%s' % package


def _HasClasses(jar_path):
  """Returns whether the given jar contains classes.dex."""
  with zipfile.ZipFile(jar_path) as jar:
    return 'classes.dex' in jar.namelist()


def Uninstall(device, package, enable_device_cache=False):
  """Uninstalls and removes all incremental files for the given package."""
  main_timer = time_profile.TimeProfile()
  device.Uninstall(package)
  if enable_device_cache:
    # Uninstall is rare, so just wipe the cache in this case.
    cache_path = _DeviceCachePath(device)
    if os.path.exists(cache_path):
      os.unlink(cache_path)
  device.RunShellCommand(['rm', '-rf', _GetDeviceIncrementalDir(package)],
                         check_return=True)
  logging.info('Uninstall took %s seconds.', main_timer.GetDelta())


def Install(device, apk, split_globs=None, native_libs=None, dex_files=None,
            enable_device_cache=False, use_concurrency=True,
            show_proguard_warning=False, permissions=(),
            allow_downgrade=True):
  """Installs the given incremental apk and all required supporting files.

  Args:
    device: A DeviceUtils instance.
    apk: The path to the apk, or an ApkHelper instance.
    split_globs: Glob patterns for any required apk splits (optional).
    native_libs: List of app's native libraries (optional).
    dex_files: List of .dex.jar files that comprise the app's Dalvik code.
    enable_device_cache: Whether to enable on-device caching of checksums.
    use_concurrency: Whether to speed things up using multiple threads.
    show_proguard_warning: Whether to print a warning about Proguard not being
        enabled after installing.
    permissions: A list of the permissions to grant, or None to grant all
                 non-blacklisted permissions in the manifest.
  """
  main_timer = time_profile.TimeProfile()
  install_timer = time_profile.TimeProfile()
  push_native_timer = time_profile.TimeProfile()
  push_dex_timer = time_profile.TimeProfile()

  apk = apk_helper.ToHelper(apk)
  apk_package = apk.GetPackageName()
  device_incremental_dir = _GetDeviceIncrementalDir(apk_package)

  # Install .apk(s) if any of them have changed.
  def do_install():
    install_timer.Start()
    if split_globs:
      splits = []
      for split_glob in split_globs:
        splits.extend((f for f in glob.glob(split_glob)))
      device.InstallSplitApk(apk, splits, reinstall=True,
                             allow_cached_props=True, permissions=permissions,
                             allow_downgrade=allow_downgrade)
    else:
      device.Install(apk, reinstall=True, permissions=permissions,
                     allow_downgrade=allow_downgrade)
    install_timer.Stop(log=False)

  # Push .so and .dex files to the device (if they have changed).
  def do_push_files():
    if native_libs:
      push_native_timer.Start()
      with build_utils.TempDir() as temp_dir:
        device_lib_dir = posixpath.join(device_incremental_dir, 'lib')
        for path in native_libs:
          # Note: Can't use symlinks as they don't work when
          # "adb push parent_dir" is used (like we do here).
          shutil.copy(path, os.path.join(temp_dir, os.path.basename(path)))
        device.PushChangedFiles([(temp_dir, device_lib_dir)],
                                delete_device_stale=True)
      push_native_timer.Stop(log=False)

    if dex_files:
      push_dex_timer.Start()
      # Put all .dex files to be pushed into a temporary directory so that we
      # can use delete_device_stale=True.
      with build_utils.TempDir() as temp_dir:
        device_dex_dir = posixpath.join(device_incremental_dir, 'dex')
        # Ensure no two files have the same name.
        transformed_names = _TransformDexPaths(dex_files)
        for src_path, dest_name in zip(dex_files, transformed_names):
          # Binary targets with no extra classes create .dex.jar without a
          # classes.dex (which Android chokes on).
          if _HasClasses(src_path):
            shutil.copy(src_path, os.path.join(temp_dir, dest_name))
        device.PushChangedFiles([(temp_dir, device_dex_dir)],
                                delete_device_stale=True)
      push_dex_timer.Stop(log=False)

  def check_selinux():
    # Marshmallow has no filesystem access whatsoever. It might be possible to
    # get things working on Lollipop, but attempts so far have failed.
    # http://crbug.com/558818
    has_selinux = device.build_version_sdk >= version_codes.LOLLIPOP
    if has_selinux and apk.HasIsolatedProcesses():
      raise Exception('Cannot use incremental installs on Android L+ without '
                      'first disabling isoloated processes.\n'
                      'To do so, use GN arg:\n'
                      '    disable_incremental_isolated_processes=true')

  cache_path = _DeviceCachePath(device)
  def restore_cache():
    if not enable_device_cache:
      logging.info('Ignoring device cache')
      return
    if os.path.exists(cache_path):
      logging.info('Using device cache: %s', cache_path)
      with open(cache_path) as f:
        device.LoadCacheData(f.read())
      # Delete the cached file so that any exceptions cause it to be cleared.
      os.unlink(cache_path)
    else:
      logging.info('No device cache present: %s', cache_path)

  def save_cache():
    with open(cache_path, 'w') as f:
      f.write(device.DumpCacheData())
      logging.info('Wrote device cache: %s', cache_path)

  # Create 2 lock files:
  # * install.lock tells the app to pause on start-up (until we release it).
  # * firstrun.lock is used by the app to pause all secondary processes until
  #   the primary process finishes loading the .dex / .so files.
  def create_lock_files():
    # Creates or zeros out lock files.
    cmd = ('D="%s";'
           'mkdir -p $D &&'
           'echo -n >$D/install.lock 2>$D/firstrun.lock')
    device.RunShellCommand(cmd % device_incremental_dir, check_return=True)

  # The firstrun.lock is released by the app itself.
  def release_installer_lock():
    device.RunShellCommand('echo > %s/install.lock' % device_incremental_dir,
                           check_return=True)

  # Concurrency here speeds things up quite a bit, but DeviceUtils hasn't
  # been designed for multi-threading. Enabling only because this is a
  # developer-only tool.
  setup_timer = _Execute(
      use_concurrency, create_lock_files, restore_cache, check_selinux)

  _Execute(use_concurrency, do_install, do_push_files)

  finalize_timer = _Execute(use_concurrency, release_installer_lock, save_cache)

  logging.info(
      'Took %s seconds (setup=%s, install=%s, libs=%s, dex=%s, finalize=%s)',
      main_timer.GetDelta(), setup_timer.GetDelta(), install_timer.GetDelta(),
      push_native_timer.GetDelta(), push_dex_timer.GetDelta(),
      finalize_timer.GetDelta())
  if show_proguard_warning:
    logging.warning('Target had proguard enabled, but incremental install uses '
                    'non-proguarded .dex files. Performance characteristics '
                    'may differ.')


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('apk_path',
                      help='The path to the APK to install.')
  parser.add_argument('--split',
                      action='append',
                      dest='splits',
                      help='A glob matching the apk splits. '
                           'Can be specified multiple times.')
  parser.add_argument('--native_lib',
                      dest='native_libs',
                      help='Path to native library (repeatable)',
                      action='append',
                      default=[])
  parser.add_argument('--dex-file',
                      dest='dex_files',
                      help='Path to dex files (repeatable)',
                      action='append',
                      default=[])
  parser.add_argument('-d', '--device', dest='device',
                      help='Target device for apk to install on.')
  parser.add_argument('--uninstall',
                      action='store_true',
                      default=False,
                      help='Remove the app and all side-loaded files.')
  parser.add_argument('--output-directory',
                      help='Path to the root build directory.')
  parser.add_argument('--no-threading',
                      action='store_false',
                      default=True,
                      dest='threading',
                      help='Do not install and push concurrently')
  parser.add_argument('--no-cache',
                      action='store_false',
                      default=True,
                      dest='cache',
                      help='Do not use cached information about what files are '
                           'currently on the target device.')
  parser.add_argument('--show-proguard-warning',
                      action='store_true',
                      default=False,
                      help='Print a warning about proguard being disabled')
  parser.add_argument('--dont-even-try',
                      help='Prints this message and exits.')
  parser.add_argument('-v',
                      '--verbose',
                      dest='verbose_count',
                      default=0,
                      action='count',
                      help='Verbose level (multiple times for more)')
  parser.add_argument('--disable-downgrade',
                      action='store_false',
                      default=True,
                      dest='allow_downgrade',
                      help='Disable install of apk with lower version number'
                           'than the version already on the device.')

  args = parser.parse_args()

  run_tests_helper.SetLogLevel(args.verbose_count)
  constants.SetBuildType('Debug')
  if args.output_directory:
    constants.SetOutputDirectory(args.output_directory)

  devil_chromium.Initialize(output_directory=constants.GetOutDirectory())

  if args.dont_even_try:
    logging.fatal(args.dont_even_try)
    return 1

  # Retries are annoying when commands fail for legitimate reasons. Might want
  # to enable them if this is ever used on bots though.
  device = device_utils.DeviceUtils.HealthyDevices(
      device_arg=args.device,
      default_retries=0,
      enable_device_files_cache=True)[0]

  apk = apk_helper.ToHelper(args.apk_path)
  if args.uninstall:
    Uninstall(device, apk.GetPackageName(), enable_device_cache=args.cache)
  else:
    Install(device, apk, split_globs=args.splits, native_libs=args.native_libs,
            dex_files=args.dex_files, enable_device_cache=args.cache,
            use_concurrency=args.threading,
            show_proguard_warning=args.show_proguard_warning,
            allow_downgrade=args.allow_downgrade)


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