# 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 json
import optparse
import os
import subprocess
import sys
import unittest

from variable_expander import VariableExpander
import verifier_runner


class Config:
  """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, test, config, variable_expander):
    """Constructor.

    Args:
      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._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 'Test: %s\n' % (' -> '.join(self._test))

  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]
      RunCommand(self._config.actions[action], self._variable_expander)

      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.
    """
    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__))
  exit_status = subprocess.call(expanded_command, shell=True, cwd=script_dir)
  if exit_status != 0:
    raise Exception('Command %s returned non-zero exit status %s' % (
        expanded_command, exit_status))


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

  Args:
    force_clean: A boolean indicating whether to force cleaning existing
        installations.
    variable_expander: A VariableExpander object.
  """
  # TODO(sukolsak): Read the clean state from the config file and clean
  # the machine according to it.
  # TODO(sukolsak): Handle Chrome SxS installs.
  commands = []
  interactive_option = '--interactive' if not force_clean else ''
  for level_option in ('', '--system-level'):
    commands.append('python uninstall_chrome.py '
                    '--chrome-long-name="$CHROME_LONG_NAME" '
                    '--no-error-if-absent %s %s' %
                    (level_option, interactive_option))
  RunCommand(' && '.join(commands), 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 ParsePropertyFiles(directory, filenames):
  """Parses an array of .prop files.

  Args:
    property_filenames: An array of Property filenames.
    directory: The directory where the Config file and all Property files
        reside in.

  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))
    MergePropertyDictionaries(current_property, new_property)
  return current_property


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

  Args:
    config_filename: A Config filename.

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

  config = Config()
  config.tests = config_data['tests']
  for state_name, state_property_filenames in config_data['states']:
    config.states[state_name] = ParsePropertyFiles(directory,
                                                   state_property_filenames)
  for action_name, action_command in config_data['actions']:
    config.actions[action_name] = action_command
  return config


def RunTests(mini_installer_path, config, force_clean):
  """Tests the installer using the given Config object.

  Args:
    mini_installer_path: The path to mini_installer.exe.
    config: A Config object.
    force_clean: A boolean indicating whether to force cleaning existing
        installations.

  Returns:
    True if all the tests passed, or False otherwise.
  """
  suite = unittest.TestSuite()
  variable_expander = VariableExpander(mini_installer_path)
  RunCleanCommand(force_clean, variable_expander)
  for test in config.tests:
    suite.addTest(InstallerTest(test, config, variable_expander))
  result = unittest.TextTestRunner(verbosity=2).run(suite)
  return result.wasSuccessful()


def IsComponentBuild(mini_installer_path):
  """ Invokes the mini_installer asking whether it is a component build.

  Args:
    mini_installer_path: The path to mini_installer.exe.

  Returns:
    True if the mini_installer is a component build, False otherwise.
  """
  query_command = mini_installer_path + ' --query-component-build'
  script_dir = os.path.dirname(os.path.abspath(__file__))
  exit_status = subprocess.call(query_command, shell=True, cwd=script_dir)
  return exit_status != 0


def main():
  usage = 'usage: %prog [options] config_filename'
  parser = optparse.OptionParser(usage, description='Test the installer.')
  parser.add_option('--build-dir', default='out',
                    help='Path to main build directory (the parent of the '
                         'Release or Debug directory)')
  parser.add_option('--target', default='Release',
                    help='Build target (Release or Debug)')
  parser.add_option('--force-clean', action='store_true', dest='force_clean',
                    default=False, help='Force cleaning existing installations')
  options, args = parser.parse_args()
  if len(args) != 1:
    parser.error('Incorrect number of arguments.')
  config_filename = args[0]

  mini_installer_path = os.path.join(options.build_dir, options.target,
                                     'mini_installer.exe')
  assert os.path.exists(mini_installer_path), ('Could not find file %s' %
                                               mini_installer_path)

  # Set the env var used by mini_installer.exe to decide to not show UI.
  os.environ['MINI_INSTALLER_TEST'] = '1'
  if IsComponentBuild(mini_installer_path):
    print ('Component build is currently unsupported by the mini_installer: '
           'http://crbug.com/377839')
    return 0

  config = ParseConfigFile(config_filename)
  if not RunTests(mini_installer_path, config, options.force_clean):
    return 1
  return 0


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