# 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.

"""This script tests the installer with test cases specified in the config file.

For each test case, it checks that the machine states after the execution of
each command match the expected machine states. For more details, take a look at
the design documentation at http://goo.gl/Q0rGM6
"""

import argparse
import contextlib
import json
import logging
import os
import shutil
import subprocess
import sys
import time
import traceback
import unittest
import win32api
from win32com.shell import shell, shellcon
import _winreg

from variable_expander import VariableExpander
import verifier_runner

# Use absolute paths
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
SRC_DIR = os.path.join(THIS_DIR, '..', '..', '..')
RUNNING_LOCALLY = (
  os.getenv('SWARMING_HEADLESS') != '1' and os.getenv('CHROME_HEADLESS') != '1')


def GetArgumentParser(doc=__doc__):
  """Gets a parser object with this module's args.

  args:
    info: The info text to use

  Returns:
    A filled out ArgumentParser instance.
  """
  # TODO(mmeade): Replace --build-dir and --target with a new path
  # flags and plumb it through.
  parser = argparse.ArgumentParser(
    description=doc, formatter_class=argparse.RawDescriptionHelpFormatter)
  parser.add_argument('-q', '--quiet', action='store_true', default=False,
                      help='Reduce test runner output')
  parser.add_argument('-v', '--verbose', action='store_true', default=False,
                      help='Increase test runner output')
  parser.add_argument('--build-dir', default='',
                      help='Path to main build directory (the parent of the '
                      'Release or Debug directory)')
  parser.add_argument('--target', default='',
                      help='Build target (Release or Debug)')
  parser.add_argument('--force-clean', action='store_true', default=False,
                      help='Force cleaning existing installations')
  parser.add_argument('--write-full-results-to', metavar='FILENAME',
                      help='Path to write the list of full results to.')
  parser.add_argument('--output-dir', metavar='DIR',
                      help='Directory into which crash dumps and other output '
                      ' files are to be written')
  # Here to satisfy the isolated script test interface. See
  # //testing/scripts/run_isolated_script_test.py
  parser.add_argument('--test-list', metavar='FILENAME',
                      help='File path containing the list of tests to run.')
  parser.add_argument('test', nargs='*',
                      help='Name(s) of tests to run.')

  # The following flags will replace the build-dir, target, and filename arg.
  parser.add_argument('--installer-path',
                      default='mini_installer.exe',
                      metavar='FILENAME',
                      help='The path of the installer.')
  parser.add_argument('--previous-version-installer-path',
                      default='previous_version_mini_installer.exe',
                      metavar='FILENAME',
                      help='The path of the previous version installer.')
  parser.add_argument('--chromedriver-path',
                      default='chromedriver.exe',
                      help='The path to chromedriver.')
  parser.add_argument('--config', default='config.config',
                      metavar='FILENAME',
                      help='Path to test configuration file')
  return parser


class Config(object):
  """Describes the machine states, actions, and test cases.

  Attributes:
    states: A dictionary where each key is a state name and the associated value
        is a property dictionary describing that state.
    actions: A dictionary where each key is an action name and the associated
        value is the action's command.
    tests: An array of test cases.
  """
  def __init__(self):
    self.states = {}
    self.actions = {}
    self.tests = []


class InstallerTest(unittest.TestCase):
  """Tests a test case in the config file."""

  def __init__(self, name, test, config, variable_expander):
    """Constructor.

    Args:
      name: The name of this test.
      test: An array of alternating state names and action names, starting and
          ending with state names.
      config: The Config object.
      variable_expander: A VariableExpander object.
    """
    super(InstallerTest, self).__init__()
    self._name = name
    self._test = test
    self._config = config
    self._variable_expander = variable_expander
    self._verifier_runner = verifier_runner.VerifierRunner()
    self._clean_on_teardown = True

  def __str__(self):
    """Returns a string representing the test case.

    Returns:
      A string created by joining state names and action names together with
      ' -> ', for example, 'Test: clean -> install chrome -> chrome_installed'.
    """
    return '%s: %s\n' % (self._name, ' -> '.join(self._test))

  def id(self):
    """Returns the name of the test."""
    # Overridden from unittest.TestCase so that id() contains the name of the
    # test case from the config file in place of the name of this class's test
    # function.
    return unittest.TestCase.id(self).replace(self._testMethodName, self._name)

  def runTest(self):
    """Run the test case."""
    # |test| is an array of alternating state names and action names, starting
    # and ending with state names. Therefore, its length must be odd.
    self.assertEqual(1, len(self._test) % 2,
                     'The length of test array must be odd')

    state = self._test[0]
    self._VerifyState(state)

    # Starting at index 1, we loop through pairs of (action, state).
    for i in range(1, len(self._test), 2):
      action = self._test[i]
      logging.info('Beginning action %s' % action)
      RunCommand(
        self._config.actions[action], self._variable_expander)
      logging.info('Finished action %s' % action)

      state = self._test[i + 1]
      self._VerifyState(state)

    # If the test makes it here, it means it was successful, because RunCommand
    # and _VerifyState throw an exception on failure.
    self._clean_on_teardown = False

  def tearDown(self):
    """Cleans up the machine if the test case fails."""
    if self._clean_on_teardown:
      RunCleanCommand(True, self._variable_expander)

  def shortDescription(self):
    """Overridden from unittest.TestCase.

    We return None as the short description to suppress its printing.
    The default implementation of this method returns the docstring of the
    runTest method, which is not useful since it's the same for every test case.
    The description from the __str__ method is informative enough.
    """
    return None

  def _VerifyState(self, state):
    """Verifies that the current machine state matches a given state.

    Args:
      state: A state name.
    """
    logging.info('Verifying state %s' % state)
    try:
      self._verifier_runner.VerifyAll(self._config.states[state],
                                      self._variable_expander)
    except AssertionError as e:
      # If an AssertionError occurs, we intercept it and add the state name
      # to the error message so that we know where the test fails.
      raise AssertionError("In state '%s', %s" % (state, e))


def RunCommand(command, variable_expander):
  """Runs the given command from the current file's directory.

  This function throws an Exception if the command returns with non-zero exit
  status.

  Args:
    command: A command to run. It is expanded using Expand.
    variable_expander: A VariableExpander object.
  """
  expanded_command = variable_expander.Expand(command)
  script_dir = os.path.dirname(os.path.abspath(__file__))
  returncode = None
  stdout = ''
  stderr = ''
  # Uninstall is special in that it is run in interactive mode and may need user
  # input. This needs to happen even if the quiet arg is passed to prevent a
  # deadlock
  if 'uninstall_chrome.py' in expanded_command:
    returncode = subprocess.call(
      expanded_command, shell=True, cwd=script_dir)
  else:
    proc = subprocess.Popen(
      expanded_command, shell=True, cwd=script_dir, stdout=subprocess.PIPE,
      stderr=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    returncode = proc.returncode

  if stdout:
    logging.info('stdout:\n%s', stdout.replace('\r', '').rstrip('\n'))
  if stderr:
    logging.error('stdout:\n%s', stderr.replace('\r', '').rstrip('\n'))
  if returncode != 0:
    raise Exception('Command %s returned non-zero exit status %s' % (
        expanded_command, returncode))


def DeleteGoogleUpdateRegistration(system_level, registry_subkey,
                                   variable_expander):
  """Deletes Chrome's registration with Google Update.

  Args:
    system_level: True if system-level Chrome is to be deleted.
    registry_subkey: The pre-expansion registry subkey for the product.
    variable_expander: A VariableExpander object.
  """
  root = (_winreg.HKEY_LOCAL_MACHINE if system_level
          else _winreg.HKEY_CURRENT_USER)
  key_name = variable_expander.Expand(registry_subkey)
  try:
    key_handle = _winreg.OpenKey(root, key_name, 0,
                                 _winreg.KEY_SET_VALUE |
                                 _winreg.KEY_WOW64_32KEY)
    _winreg.DeleteValue(key_handle, 'pv')
  except WindowsError:
    # The key isn't present, so there is no value to delete.
    pass


def RunCleanCommand(force_clean, variable_expander):
  """Puts the machine in the clean state (e.g. Chrome not installed).

  Args:
    force_clean: A boolean indicating whether to force cleaning existing
        installations.
    variable_expander: A VariableExpander object.
  """
  # A list of (system_level, product_name, product_switch, registry_subkey)
  # tuples for the possible installed products.
  data = [
    (False, '$CHROME_LONG_NAME', '',
     '$CHROME_UPDATE_REGISTRY_SUBKEY'),
    (True, '$CHROME_LONG_NAME', '--system-level',
     '$CHROME_UPDATE_REGISTRY_SUBKEY'),
  ]
  if variable_expander.Expand('$BRAND') == 'Google Chrome':
    data.extend([(False, '$CHROME_LONG_NAME_BETA', '',
                  '$CHROME_UPDATE_REGISTRY_SUBKEY_BETA'),
                 (True, '$CHROME_LONG_NAME_BETA', '--system-level',
                  '$CHROME_UPDATE_REGISTRY_SUBKEY_BETA'),
                 (False, '$CHROME_LONG_NAME_DEV', '',
                  '$CHROME_UPDATE_REGISTRY_SUBKEY_DEV'),
                 (True, '$CHROME_LONG_NAME_DEV', '--system-level',
                  '$CHROME_UPDATE_REGISTRY_SUBKEY_DEV'),
                 (False, '$CHROME_LONG_NAME_SXS', '',
                  '$CHROME_UPDATE_REGISTRY_SUBKEY_SXS')])

  interactive_option = '--interactive' if not force_clean else ''
  for system_level, product_name, product_switch, registry_subkey in data:
    command = ('python uninstall_chrome.py '
               '--chrome-long-name="%s" '
               '--no-error-if-absent %s %s' %
               (product_name, product_switch, interactive_option))
    try:
      RunCommand(command, variable_expander)
    except:
      message = traceback.format_exception(*sys.exc_info())
      message.insert(0, 'Error cleaning up an old install with:\n')
      logging.info(''.join(message))
    if force_clean:
      DeleteGoogleUpdateRegistration(system_level, registry_subkey,
                                     variable_expander)


def MergePropertyDictionaries(current_property, new_property):
  """Merges the new property dictionary into the current property dictionary.

  This is different from general dictionary merging in that, in case there are
  keys with the same name, we merge values together in the first level, and we
  override earlier values in the second level. For more details, take a look at
  http://goo.gl/uE0RoR

  Args:
    current_property: The property dictionary to be modified.
    new_property: The new property dictionary.
  """
  for key, value in new_property.iteritems():
    if key not in current_property:
      current_property[key] = value
    else:
      assert(isinstance(current_property[key], dict) and
          isinstance(value, dict))
      # This merges two dictionaries together. In case there are keys with
      # the same name, the latter will override the former.
      current_property[key] = dict(
          current_property[key].items() + value.items())


def FilterConditionalElem(elem, condition_name, variable_expander):
  """Returns True if a conditional element should be processed.

  Args:
    elem: A dictionary.
    condition_name: The name of the condition property in |elem|.
    variable_expander: A variable expander used to evaluate conditions.

  Returns:
    True if |elem| should be processed.
  """
  if condition_name not in elem:
    return True
  condition = variable_expander.Expand(elem[condition_name])
  return eval(condition, {'__builtins__': {'False': False, 'True': True}})


def ParsePropertyFiles(directory, filenames, variable_expander):
  """Parses an array of .prop files.

  Args:
    directory: The directory where the Config file and all Property files
        reside in.
    filenames: An array of Property filenames.
    variable_expander: A variable expander used to evaluate conditions.

  Returns:
    A property dictionary created by merging all property dictionaries specified
        in the array.
  """
  current_property = {}
  for filename in filenames:
    path = os.path.join(directory, filename)
    new_property = json.load(open(path))
    if not FilterConditionalElem(new_property, 'Condition', variable_expander):
      continue
    # Remove any Condition from the propery dict before merging since it serves
    # no purpose from here on out.
    if 'Condition' in new_property:
      del new_property['Condition']
    MergePropertyDictionaries(current_property, new_property)
  return current_property


def ParseConfigFile(filename, variable_expander):
  """Parses a .config file.

  Args:
    config_filename: A Config filename.

  Returns:
    A Config object.
  """
  with open(filename, 'r') as fp:
    config_data = json.load(fp)
  directory = os.path.dirname(os.path.abspath(filename))

  config = Config()
  config.tests = config_data['tests']
  # Drop conditional tests that should not be run in the current configuration.
  config.tests = filter(lambda t: FilterConditionalElem(t, 'condition',
                                                        variable_expander),
                        config.tests)
  for state_name, state_property_filenames in config_data['states']:
    config.states[state_name] = ParsePropertyFiles(directory,
                                                   state_property_filenames,
                                                   variable_expander)
  for action_name, action_command in config_data['actions']:
    config.actions[action_name] = action_command
  return config


@contextlib.contextmanager
def ConfigureTempOnDrive(drive):
  """Ensures that TMP is on |drive|, restoring state on completion.

  This does not change the current Python runtime's idea of tempdir.
  """
  tmp_set = False
  old_tmp = None
  tmp_created = None
  # Set TMP to something reasonable if the default temp path is not on the
  # desired drive. Note that os.environ is used to mutate the environment since
  # doing so writes through to the process's underlying environment block. Reads
  # are performed directly in the off chance that code elsewhere has modified
  # the environment without going through os.environ.
  temp = win32api.GetTempPath()
  if not temp or os.path.splitdrive(temp)[0] != drive:
    # Try to use one of the standard Temp dir locations.
    for candidate in [os.getenv(v) for v in ['LOCALAPPDATA', 'windir']]:
      if candidate and os.path.splitdrive(candidate)[0] == drive:
        temp = os.path.join(candidate, 'Temp')
        if os.path.isdir(temp):
          old_tmp = os.getenv('TMP')
          os.environ['TMP'] = temp
          tmp_set = True
          break
    # Otherwise make a Temp dir at the root of the drive.
    if not tmp_set:
      temp = os.path.join(drive, os.sep, 'Temp')
      if not os.path.exists(temp):
        os.mkdir(temp)
        tmp_created = temp
      elif not os.path.isdir(temp):
        raise Exception('Cannot create %s without clobbering something' % temp)
      old_tmp = os.getenv('TMP')
      os.environ['TMP'] = temp
      tmp_set = True
  try:
    yield
  finally:
    if tmp_set:
      if old_tmp is None:
        del os.environ['TMP']
      else:
        os.environ['TMP'] = old_tmp
    if tmp_created:
      shutil.rmtree(tmp_created, True)
      if os.path.isdir(tmp_created):
        raise Exception('Failed to entirely delete directory %s' % tmp_created)


def GetAbsoluteExecutablePath(build_dir, target, path):
  """Gets the absolute path to the an executable.

  The path can either be an absolute or relative path, as well as the
  executable's name. These are used to probe user-specified and common
  binary paths.

  This method searches for the binary in common locations:
  - path location (when specifying a non-standard location)
  - build_dir\target\path (explicitly passed via build_dir and target flags,
      path here is the filename)
  - out\Release\path (local default path, path here is the filename)
  - out\Default\path (alternate local default path)
  - out\Release_x64\path (on waterfall)

  Note: If build_dir and target are empty (default) just the path is used. This
  allows the user to pass in paths without having to worry about conflicts with
  the build_dir and target args.

  Args:
    build_dir: The build directory (e.g. out)
    target: The target directory (e.g. Release)
    path: The path to the file. This can be an absolute or relative path.

  Returns:
    Absolute path to installer.
  """
  possible_paths = [
    os.path.abspath(os.path.join(build_dir, target, path)),
    os.path.abspath(os.path.join('out', 'Release', path)),
    os.path.abspath(os.path.join('out', 'Release_x64', path)),
    os.path.abspath(os.path.join('out', 'Default', path)),
    ]
  for _path in possible_paths:
    if os.path.exists(_path):
      return _path
  raise RuntimeError('Binary can\'t be found: %s' % path)


def GetAbsoluteConfigPath(path):
  """Gets the absolute path to the config file.

  Args:
    path: The path to the file.

  Returns:
    Absolute path to config.
  """
  if os.path.exists(path):
    pass
  else:
    path = os.path.join(THIS_DIR, 'config', path)

  assert os.path.exists(path), 'Config can\'t be found: %s' % path
  logging.info('Config found at %s', path)
  return os.path.abspath(path)


def DoMain():
  parser = GetArgumentParser()
  args = parser.parse_args()

  tests_to_run = args.test
  if args.test_list:
    if tests_to_run:
      parser.error('cannot specify both --test-list and |test|')

    with open(args.test_list) as f:
      tests_to_run = [test.strip() for test in f.readlines()]

  # Due to what looks like a bug the root handlers need to be cleared out
  # so the right handler will be created.
  logging.Logger.root.handlers = []
  log_level = (logging.ERROR if args.quiet else
               logging.DEBUG if args.verbose else
               logging.INFO)
  logging.basicConfig(
    format='[%(asctime)s:%(filename)s(%(lineno)d)] %(message)s',
    datefmt='%m%d/%H%M%S', level=log_level)

  # TODO(mmeade): Fully switch to paths
  # Use absolute paths.
  installer_path = GetAbsoluteExecutablePath(
    args.build_dir, args.target, args.installer_path)
  previous_version_installer_path = GetAbsoluteExecutablePath(
    args.build_dir, args.target, args.previous_version_installer_path)
  chromedriver_path = GetAbsoluteExecutablePath(
    args.build_dir, args.target, args.chromedriver_path)
  config_path = GetAbsoluteConfigPath(args.config)

  # Set --force-clean when not running locally
  if not RUNNING_LOCALLY:
    logging.info('Setting --force-clean')
    args.force_clean = True

  suite = unittest.TestSuite()

  variable_expander = VariableExpander(installer_path,
                                       previous_version_installer_path,
                                       chromedriver_path,
                                       args.quiet,
                                       args.output_dir)
  config = ParseConfigFile(config_path, variable_expander)

  RunCleanCommand(args.force_clean, variable_expander)
  for test in config.tests:
    # If tests were specified via |tests|, their names are formatted like so:
    test_name = '%s.%s.%s' % (InstallerTest.__module__,
                              InstallerTest.__name__,
                              test['name'])
    if not tests_to_run or test_name in tests_to_run:
      suite.addTest(InstallerTest(test['name'], test['traversal'], config,
                                  variable_expander))

  verbosity = 2 if not args.quiet else 1
  result = unittest.TextTestRunner(verbosity=verbosity).run(suite)
  if args.write_full_results_to:
    with open(args.write_full_results_to, 'w') as fp:
      json.dump(_FullResults(suite, result, {}), fp, indent=2)
      fp.write('\n')
  return 0 if result.wasSuccessful() else 1


def main():
  # Make sure that TMP and Chrome's installation directory are on the same
  # drive to work around https://crbug.com/700809. (CSIDL_PROGRAM_FILESX86 is
  # valid for both 32 and 64-bit apps running on 32 or 64-bit Windows.)
  drive = os.path.splitdrive(
      shell.SHGetFolderPath(0, shellcon.CSIDL_PROGRAM_FILESX86, None, 0))[0]
  with ConfigureTempOnDrive(drive):
    return DoMain()


# TODO(dpranke): Find a way for this to be shared with the mojo and other tests.
TEST_SEPARATOR = '.'


def _FullResults(suite, result, metadata):
  """Convert the unittest results to the Chromium JSON test result format.

  This matches run_web_tests.py (the layout tests) and the flakiness dashboard.
  """

  full_results = {}
  full_results['interrupted'] = False
  full_results['path_delimiter'] = TEST_SEPARATOR
  full_results['version'] = 3
  full_results['seconds_since_epoch'] = time.time()
  for md in metadata:
    key, val = md.split('=', 1)
    full_results[key] = val

  all_test_names = _AllTestNames(suite)
  failed_test_names = _FailedTestNames(result)

  full_results['num_failures_by_type'] = {
      'FAIL': len(failed_test_names),
      'PASS': len(all_test_names) - len(failed_test_names),
  }

  full_results['tests'] = {}

  for test_name in all_test_names:
    value = {}
    value['expected'] = 'PASS'
    if test_name in failed_test_names:
      value['actual'] = 'FAIL'
      value['is_unexpected'] = True
    else:
      value['actual'] = 'PASS'
    _AddPathToTrie(full_results['tests'], test_name, value)

  return full_results


def _AllTestNames(suite):
  test_names = []
  # _tests is protected  pylint: disable=W0212
  for test in suite._tests:
    if isinstance(test, unittest.suite.TestSuite):
      test_names.extend(_AllTestNames(test))
    else:
      test_names.append(test.id())
  return test_names


def _FailedTestNames(result):
  return set(test.id() for test, _ in result.failures + result.errors)


def _AddPathToTrie(trie, path, value):
  if TEST_SEPARATOR not in path:
    trie[path] = value
    return
  directory, rest = path.split(TEST_SEPARATOR, 1)
  if directory not in trie:
    trie[directory] = {}
  _AddPathToTrie(trie[directory], rest, value)


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