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

import logging
import os
import re
import sys

_logging = logging.getLogger()

from mopy import test_util
from mopy.background_app_group import BackgroundAppGroup
from mopy.config import Config
from mopy.paths import Paths
from mopy.print_process_error import print_process_error


def set_color():
  """Run gtests with color if we're on a TTY (and we're not being told
  explicitly what to do)."""
  if sys.stdout.isatty() and "GTEST_COLOR" not in os.environ:
    _logging.debug("Setting GTEST_COLOR=yes")
    os.environ["GTEST_COLOR"] = "yes"

def run_fixtures(config, apptest_dict, apptest, test_args, shell_args,
                 launched_services):
  """Run the gtest fixtures in isolation."""

  mojo_paths = Paths(config)

  # List the apptest fixtures so they can be run independently for isolation.
  # TODO(msw): Run some apptests without fixture isolation?
  fixtures = get_fixtures(config, shell_args, apptest)

  if not fixtures:
    return "Failed with no tests found."

  if any(not mojo_paths.IsValidAppUrl(url) for url in launched_services):
    return ("Failed with malformed launched-services: %r" % launched_services)

  apptest_result = "Succeeded"
  for fixture in fixtures:
    apptest_args = test_args + ["--gtest_filter=%s" % fixture]
    if launched_services:
      success = RunApptestInLauncher(config, mojo_paths, apptest, apptest_args,
                                     shell_args, launched_services)
    else:
      success = RunApptestInShell(config, apptest, apptest_args, shell_args)

    if not success:
      apptest_result = "Failed test(s) in %r" % apptest_dict

  return apptest_result


def run_test(config, shell_args, apps_and_args=None, run_launcher=False):
  """Runs a command line and checks the output for signs of gtest failure.

  Args:
    config: The mopy.config.Config object for the build.
    shell_args: The arguments for mojo_shell.
    apps_and_args: A Dict keyed by application URL associated to the
        application's specific arguments.
    run_launcher: |True| is mojo_launcher must be used instead of mojo_shell.
  """
  apps_and_args = apps_and_args or {}
  output = test_util.try_run_test(config, shell_args, apps_and_args,
                                  run_launcher)
  # Fail on output with gtest's "[  FAILED  ]" or a lack of "[  PASSED  ]".
  # The latter condition ensures failure on broken command lines or output.
  # Check output instead of exit codes because mojo_shell always exits with 0.
  if (output is None or
      (output.find("[  FAILED  ]") != -1 or output.find("[  PASSED  ]") == -1)):
    print "Failed test:"
    print_process_error(
        test_util.build_command_line(config, shell_args, apps_and_args,
                                     run_launcher),
        output)
    return False
  _logging.debug("Succeeded with output:\n%s" % output)
  return True


def get_fixtures(config, shell_args, apptest):
  """Returns the "Test.Fixture" list from an apptest using mojo_shell.

  Tests are listed by running the given apptest in mojo_shell and passing
  --gtest_list_tests. The output is parsed and reformatted into a list like
  [TestSuite.TestFixture, ... ]
  An empty list is returned on failure, with errors logged.

  Args:
    config: The mopy.config.Config object for the build.
    apptest: The URL of the test application to run.
  """
  try:
    apps_and_args = {apptest: ["--gtest_list_tests"]}
    list_output = test_util.run_test(config, shell_args, apps_and_args)
    _logging.debug("Tests listed:\n%s" % list_output)
    return _gtest_list_tests(list_output)
  except Exception as e:
    print "Failed to get test fixtures:"
    print_process_error(
        test_util.build_command_line(config, shell_args, apps_and_args), e)
  return []


def _gtest_list_tests(gtest_list_tests_output):
  """Returns a list of strings formatted as TestSuite.TestFixture from the
  output of running --gtest_list_tests on a GTEST application."""

  # Remove log lines.
  gtest_list_tests_output = (
      re.sub("^\[.*\n", "", gtest_list_tests_output, flags=re.MULTILINE))

  if not re.match("^(\w*\.\r?\n(  \w*\r?\n)+)+", gtest_list_tests_output):
    raise Exception("Unrecognized --gtest_list_tests output:\n%s" %
                    gtest_list_tests_output)

  output_lines = gtest_list_tests_output.split("\n")

  test_list = []
  for line in output_lines:
    if not line:
      continue
    if line[0] != " ":
      suite = line.strip()
      continue
    test_list.append(suite + line.strip())

  return test_list


def RunApptestInShell(config, application, application_args, shell_args):
  return run_test(config, shell_args, {application: application_args})


def RunApptestInLauncher(config, mojo_paths, application, application_args,
                         shell_args, launched_services):
  with BackgroundAppGroup(
      mojo_paths, launched_services,
      test_util.build_shell_arguments(shell_args)) as apps:
    launcher_args = [
        '--shell-path=' + apps.socket_path,
        '--app-url=' + application,
        '--app-path=' + mojo_paths.FileFromUrl(application),
        '--app-args=' + " ".join(application_args)]
    return run_test(config, launcher_args, run_launcher=True)
