#!/usr/bin/env vpython
# 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.

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

from __future__ import print_function

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)
  elif 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())
