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

"""Utility for reading / writing command-line flag files on device(s)."""


import argparse
import logging
import sys

import devil_chromium

from devil.android import device_errors
from devil.android import device_utils
from devil.android import flag_changer
from devil.android.tools import script_common
from devil.utils import cmd_helper
from devil.utils import logging_common


def CheckBuildTypeSupportsFlags(device, command_line_flags_file):
  is_webview = command_line_flags_file == 'webview-command-line'
  if device.IsUserBuild() and is_webview:
    raise device_errors.CommandFailedError(
        'WebView only respects flags on a userdebug or eng device, yours '
        'is a user build.', device)
  if device.IsUserBuild():
    logging.warning(
        'Your device (%s) is a user build; Chrome may or may not pick up '
        'your commandline flags. Check your '
        '"command_line_on_non_rooted_enabled" preference, or switch '
        'devices.', device)


def main():
  parser = argparse.ArgumentParser(description=__doc__)
  parser.usage = '''%(prog)s --name FILENAME [--device SERIAL] [flags...]

No flags: Prints existing command-line file.
Empty string: Deletes command-line file.
Otherwise: Writes command-line file.

'''
  parser.add_argument('--name', required=True,
                      help='Name of file where to store flags on the device.')
  parser.add_argument('-e', '--executable', dest='executable', default='chrome',
                      help='(deprecated) No longer used.')
  script_common.AddEnvironmentArguments(parser)
  script_common.AddDeviceArguments(parser)
  logging_common.AddLoggingArguments(parser)

  args, remote_args = parser.parse_known_args()
  devil_chromium.Initialize(adb_path=args.adb_path)
  logging_common.InitializeLogging(args)

  devices = device_utils.DeviceUtils.HealthyDevices(device_arg=args.devices,
                                                    default_retries=0)
  all_devices = device_utils.DeviceUtils.parallel(devices)

  if not remote_args:
    # No args == do not update, just print flags.
    remote_args = None
    action = ''
  elif len(remote_args) == 1 and not remote_args[0]:
    # Single empty string arg == delete flags
    remote_args = []
    action = 'Deleted command line file. '
  else:
    action = 'Wrote command line file. '

  def update_flags(device):
    CheckBuildTypeSupportsFlags(device, args.name)
    changer = flag_changer.FlagChanger(device, args.name)
    if remote_args is not None:
      flags = changer.ReplaceFlags(remote_args)
    else:
      flags = changer.GetCurrentFlags()
    return (device, device.build_description, flags)

  updated_values = all_devices.pMap(update_flags).pGet(None)

  print('%sCurrent flags (in %s):' % (action, args.name))
  for d, desc, flags in updated_values:
    if flags:
      # Shell-quote flags for easy copy/paste as new args on the terminal.
      quoted_flags = ' '.join(cmd_helper.SingleQuote(f) for f in sorted(flags))
    else:
      quoted_flags = '( empty )'
    print('  %s (%s): %s' % (d, desc, quoted_flags))

  return 0


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