# Copyright 2020 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.
"""
This script runs Chrome and automatically navigates through the given list of
URLs the specified number of times.

Usage: vpython auto-nav.py <chrome dir> <number of navigations> <url> <url> ...

Optional flags:
* --interval <seconds>, -i <seconds>: specify a number of seconds to wait
                                      between navigations, e.g., -i=5
* --wait, -w: start Chrome, then wait for the user to press any key before
              starting auto-navigation
* --idlewakeups_dir: Windows only; specify the directory containing
                     idlewakeups.exe to print measurements taken by IdleWakeups,
                     e.g., --idlewakeups_dir=tools/win/IdleWakeups/x64/Debug

Optional flags to chrome.exe, example:
-- --user-data-dir=temp --disable-features=SomeFeature
Note: must be at end of command, following options terminator "--". The options
terminator stops command-line options from being interpreted as options for this
script, which would cause an unrecognized-argument error.
"""

# [VPYTHON:BEGIN]
# python_version: "2.7"
# wheel: <
#   name: "infra/python/wheels/selenium-py2_py3"
#   version: "version:3.14.0"
# >
# wheel: <
#   name: "infra/python/wheels/urllib3-py2_py3"
#   version: "version:1.24.3"
# >
# wheel: <
#   name: "infra/python/wheels/psutil/${vpython_platform}"
#   version: "version:5.6.2"
# >
# [VPYTHON:END]

import argparse
import os
import subprocess
import sys
import time

try:
  import psutil
  from selenium import webdriver
except ImportError:
  print('Error importing required modules. Run with vpython instead of python.')
  sys.exit(1)

DEFAULT_INTERVAL = 1


# Splits list |positional_args| into two lists: |urls| and |chrome_args|, where
# arguments starting with '-' are treated as chrome args, and the rest as URLs.
def ParsePositionalArgs(positional_args):
  urls, chrome_args = [], []
  for arg in positional_args:
    if arg.startswith('-'):
      chrome_args.append(arg)
    else:
      urls.append(arg)
  return [urls, chrome_args]


# Returns an object containing the arguments parsed from this script's command
# line.
def ParseArgs():
  # Customize usage and help to include options to be passed to chrome.exe.
  usage_text = '''%(prog)s [-h] [--interval INTERVAL] [--wait]
                   [--idlewakeups_dir IDLEWAKEUPS_DIR]
                   chrome_dir num_navigations url [url ...]
                   [-- --chrome_option ...]'''
  additional_help_text = '''optional arguments to chrome.exe, example:
  -- --enable-features=MyFeature --browser-startup-dialog
                        Must be at end of command, following the options
                        terminator "--"'''
  parser = argparse.ArgumentParser(
      epilog=additional_help_text,
      usage=usage_text,
      formatter_class=argparse.RawDescriptionHelpFormatter)
  parser.add_argument(
      'chrome_dir', help='Directory containing chrome.exe and chromedriver.exe')
  parser.add_argument('num_navigations',
                      type=int,
                      help='Number of times to navigate through list of URLs')
  parser.add_argument('--interval',
                      '-i',
                      type=int,
                      help='Seconds to wait between navigations; default is 1')
  parser.add_argument('--wait',
                      '-w',
                      action='store_true',
                      help='Wait for confirmation before beginning navigation')
  parser.add_argument(
      '--idlewakeups_dir',
      help='Windows only; directory containing idlewakeups.exe, if using')
  parser.add_argument(
      'url',
      nargs='+',
      help='URL(s) to navigate, separated by spaces; must include scheme, '
      'e.g., "https://"')
  args = parser.parse_args()
  args.url, chrome_args = ParsePositionalArgs(args.url)
  if not args.url:
    parser.print_usage()
    print(os.path.basename(__file__) + ': error: missing URL argument')
    exit(1)
  return [args, chrome_args]


# If |path| does not exist, prints a generic error plus optional |error_message|
# and exits.
def ExitIfNotFound(path, error_message=None):
  if not os.path.exists(path):
    print('File not found: {}.'.format(path))
    if error_message:
      print(error_message)
    exit()


def main():
  # Parse arguments and check that file paths received are valid.
  args, chrome_args = ParseArgs()
  ExitIfNotFound(os.path.join(args.chrome_dir, 'chrome.exe'),
                 'Build target "chrome" to generate it first.')
  chromedriver_exe = os.path.join(args.chrome_dir, 'chromedriver.exe')
  ExitIfNotFound(chromedriver_exe,
                 'Build target "chromedriver" to generate it first.')
  if args.idlewakeups_dir:
    idlewakeups_exe = os.path.join(args.idlewakeups_dir, 'idlewakeups.exe')
    ExitIfNotFound(idlewakeups_exe)

  # Start chrome.exe. Disable chrome.exe's extensive logging to make reading
  # this script's output easier.
  chrome_options = webdriver.ChromeOptions()
  chrome_options.add_experimental_option('excludeSwitches', ['enable-logging'])
  for arg in chrome_args:
    chrome_options.add_argument(arg)
  driver = webdriver.Chrome(os.path.abspath(chromedriver_exe),
                            options=chrome_options)

  if args.wait:
    driver.get(args.url[0])
    raw_input('Press Enter to begin navigation...')

  # Start IdleWakeups, if using, passing the browser process's ID as its target.
  # IdleWakeups will monitor the browser process and its children. Other running
  # chrome.exe processes (i.e., those not launched by this script) are excluded.
  if args.idlewakeups_dir:
    launched_processes = psutil.Process(
        driver.service.process.pid).children(recursive=False)
    if not launched_processes:
      print('Error getting browser process ID for IdleWakeups.')
      exit()
    # Assume the first child process created by |driver| is the browser process.
    idlewakeups = subprocess.Popen([
        idlewakeups_exe,
        str(launched_processes[0].pid), '--stop-on-exit', '--tabbed'
    ],
                                   stdout=subprocess.PIPE)

  # Navigate through |args.url| list |args.num_navigations| times, then close
  # chrome.exe.
  interval = args.interval if args.interval else DEFAULT_INTERVAL
  for _ in range(args.num_navigations):
    for url in args.url:
      driver.get(url)
      time.sleep(interval)
  driver.quit()

  # Print IdleWakeups' output, if using.
  if args.idlewakeups_dir:
    print(idlewakeups.communicate()[0])


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