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

"""Runs semi-automated update testing on a non-rooted device.

This script will help verify that app data is preserved during an update.
To use this script first run it with the create_app_data option.

./update_verification.py create_app_data --old-apk <path> --app-data <path>

The script will then install the old apk, prompt you to create some app data
(bookmarks, etc.), and then save the app data in the path you gave it.

Next, once you have some app data saved, run this script with the test_update
option.

./update_verification.py test_update --old-apk <path> --new-apk <path>
--app-data <path>

This will install the old apk, load the saved app data, install the new apk,
and ask the user to verify that all of the app data was preserved.
"""

import argparse
import logging
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

def CreateAppData(device, old_apk, app_data, package_name):
  device.Install(old_apk)
  raw_input('Set the application state. Once ready, press enter and '
            'select "Backup my data" on the device.')
  device.adb.Backup(app_data, packages=[package_name])
  logging.critical('Application data saved to %s', app_data)

def TestUpdate(device, old_apk, new_apk, app_data, package_name):
  device.Install(old_apk)
  device.adb.Restore(app_data)
  # Restore command is not synchronous
  raw_input('Select "Restore my data" on the device. Then press enter to '
            'continue.')
  if not device.IsApplicationInstalled(package_name):
    raise Exception('Expected package %s to already be installed. '
                    'Package name might have changed!' % package_name)

  logging.info('Verifying that %s can be overinstalled.', new_apk)
  device.adb.Install(new_apk, reinstall=True)
  logging.critical('Successfully updated to the new apk. Please verify that '
                   'the application data is preserved.')

def main():
  parser = argparse.ArgumentParser(
      description="Script to do semi-automated upgrade testing.")
  parser.add_argument('-v', '--verbose', action='count',
                      help='Print verbose log information.')
  parser.add_argument('--denylist-file', help='Device denylist JSON file.')
  command_parsers = parser.add_subparsers(dest='command')

  subparser = command_parsers.add_parser('create_app_data')
  subparser.add_argument('--old-apk', required=True,
                         help='Path to apk to update from.')
  subparser.add_argument('--app-data', required=True,
                         help='Path to where the app data backup should be '
                           'saved to.')
  subparser.add_argument('--package-name',
                         help='Chrome apk package name.')

  subparser = command_parsers.add_parser('test_update')
  subparser.add_argument('--old-apk', required=True,
                         help='Path to apk to update from.')
  subparser.add_argument('--new-apk', required=True,
                         help='Path to apk to update to.')
  subparser.add_argument('--app-data', required=True,
                         help='Path to where the app data backup is saved.')
  subparser.add_argument('--package-name',
                         help='Chrome apk package name.')

  args = parser.parse_args()
  run_tests_helper.SetLogLevel(args.verbose)

  devil_chromium.Initialize()

  denylist = (device_denylist.Denylist(args.denylist_file)
              if args.denylist_file else None)

  devices = device_utils.DeviceUtils.HealthyDevices(denylist)
  if not devices:
    raise device_errors.NoDevicesError()
  device = devices[0]
  logging.info('Using device %s for testing.', str(device))

  package_name = (args.package_name if args.package_name
                  else apk_helper.GetPackageName(args.old_apk))
  if args.command == 'create_app_data':
    CreateAppData(device, args.old_apk, args.app_data, package_name)
  elif args.command == 'test_update':
    TestUpdate(
        device, args.old_apk, args.new_apk, args.app_data, package_name)
  else:
    raise Exception('Unknown test command: %s' % args.command)

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