#!/usr/bin/env python
# Copyright (c) 2012 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""gyptest.py -- test runner for GYP tests."""

from __future__ import print_function

import argparse
import math
import os
import platform
import subprocess
import sys
import time


def is_test_name(f):
  return f.startswith('gyptest') and f.endswith('.py')


def find_all_gyptest_files(directory):
  result = []
  for root, dirs, files in os.walk(directory):
    result.extend([ os.path.join(root, f) for f in files if is_test_name(f) ])
  result.sort()
  return result


def main(argv=None):
  if argv is None:
    argv = sys.argv

  parser = argparse.ArgumentParser()
  parser.add_argument("-a", "--all", action="store_true",
      help="run all tests")
  parser.add_argument("-C", "--chdir", action="store",
      help="change to directory")
  parser.add_argument("-f", "--format", action="store", default='',
      help="run tests with the specified formats")
  parser.add_argument("-G", '--gyp_option', action="append", default=[],
      help="Add -G options to the gyp command line")
  parser.add_argument("-l", "--list", action="store_true",
      help="list available tests and exit")
  parser.add_argument("-n", "--no-exec", action="store_true",
      help="no execute, just print the command line")
  parser.add_argument("--path", action="append", default=[],
      help="additional $PATH directory")
  parser.add_argument("-q", "--quiet", action="store_true",
      help="quiet, don't print anything unless there are failures")
  parser.add_argument("-v", "--verbose", action="store_true",
      help="print configuration info and test results.")
  parser.add_argument('tests', nargs='*')
  args = parser.parse_args(argv[1:])

  if args.chdir:
    os.chdir(args.chdir)

  if args.path:
    extra_path = [os.path.abspath(p) for p in args.path]
    extra_path = os.pathsep.join(extra_path)
    os.environ['PATH'] = extra_path + os.pathsep + os.environ['PATH']

  if not args.tests:
    if not args.all:
      sys.stderr.write('Specify -a to get all tests.\n')
      return 1
    args.tests = ['test']

  tests = []
  for arg in args.tests:
    if os.path.isdir(arg):
      tests.extend(find_all_gyptest_files(os.path.normpath(arg)))
    else:
      if not is_test_name(os.path.basename(arg)):
        print(arg, 'is not a valid gyp test name.', file=sys.stderr)
        sys.exit(1)
      tests.append(arg)

  if args.list:
    for test in tests:
      print(test)
    sys.exit(0)

  os.environ['PYTHONPATH'] = os.path.abspath('test/lib')

  if args.verbose:
    print_configuration_info()

  if args.gyp_option and not args.quiet:
    print('Extra Gyp options: %s\n' % args.gyp_option)

  if args.format:
    format_list = args.format.split(',')
  else:
    format_list = {
      'aix5':     ['make'],
      'freebsd7': ['make'],
      'freebsd8': ['make'],
      'openbsd5': ['make'],
      'cygwin':   ['msvs'],
      'win32':    ['msvs', 'ninja'],
      'linux':    ['make', 'ninja'],
      'linux2':   ['make', 'ninja'],
      'linux3':   ['make', 'ninja'],

      # TODO: Re-enable xcode-ninja.
      # https://bugs.chromium.org/p/gyp/issues/detail?id=530
      # 'darwin':   ['make', 'ninja', 'xcode', 'xcode-ninja'],
      'darwin':   ['make', 'ninja', 'xcode'],
    }[sys.platform]

  gyp_options = []
  for option in args.gyp_option:
    gyp_options += ['-G', option]

  runner = Runner(format_list, tests, gyp_options, args.verbose)
  runner.run()

  if not args.quiet:
    runner.print_results()

  if runner.failures:
    return 1
  else:
    return 0


def print_configuration_info():
  print('Test configuration:')
  if sys.platform == 'darwin':
    sys.path.append(os.path.abspath('test/lib'))
    import TestMac
    print('  Mac %s %s' % (platform.mac_ver()[0], platform.mac_ver()[2]))
    print('  Xcode %s' % TestMac.Xcode.Version())
  elif sys.platform == 'win32':
    sys.path.append(os.path.abspath('pylib'))
    import gyp.MSVSVersion
    print('  Win %s %s\n' % platform.win32_ver()[0:2])
    print('  MSVS %s' %
          gyp.MSVSVersion.SelectVisualStudioVersion().Description())
  elif sys.platform in ('linux', 'linux2'):
    print('  Linux %s' % ' '.join(platform.linux_distribution()))
  print('  Python %s' % platform.python_version())
  print('  PYTHONPATH=%s' % os.environ['PYTHONPATH'])
  print()


class Runner(object):
  def __init__(self, formats, tests, gyp_options, verbose):
    self.formats = formats
    self.tests = tests
    self.verbose = verbose
    self.gyp_options = gyp_options
    self.failures = []
    self.num_tests = len(formats) * len(tests)
    num_digits = len(str(self.num_tests))
    self.fmt_str = '[%%%dd/%%%dd] (%%s) %%s' % (num_digits, num_digits)
    self.isatty = sys.stdout.isatty() and not self.verbose
    self.env = os.environ.copy()
    self.hpos = 0

  def run(self):
    run_start = time.time()

    i = 1
    for fmt in self.formats:
      for test in self.tests:
        self.run_test(test, fmt, i)
        i += 1

    if self.isatty:
      self.erase_current_line()

    self.took = time.time() - run_start

  def run_test(self, test, fmt, i):
    if self.isatty:
      self.erase_current_line()

    msg = self.fmt_str % (i, self.num_tests, fmt, test)
    self.print_(msg)

    start = time.time()
    cmd = [sys.executable, test] + self.gyp_options
    self.env['TESTGYP_FORMAT'] = fmt
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT, env=self.env)
    proc.wait()
    took = time.time() - start

    stdout = proc.stdout.read().decode('utf8')
    if proc.returncode == 2:
      res = 'skipped'
    elif proc.returncode:
      res = 'failed'
      self.failures.append('(%s) %s' % (test, fmt))
    else:
      res = 'passed'
    res_msg = ' %s %.3fs' % (res, took)
    self.print_(res_msg)

    if (stdout and
        not stdout.endswith('PASSED\n') and
        not (stdout.endswith('NO RESULT\n'))):
      print()
      for l in stdout.splitlines():
        print('    %s' % l)
    elif not self.isatty:
      print()

  def print_(self, msg):
    print(msg, end='')
    index = msg.rfind('\n')
    if index == -1:
      self.hpos += len(msg)
    else:
      self.hpos = len(msg) - index
    sys.stdout.flush()

  def erase_current_line(self):
    print('\b' * self.hpos + ' ' * self.hpos + '\b' * self.hpos, end='')
    sys.stdout.flush()
    self.hpos = 0

  def print_results(self):
    num_failures = len(self.failures)
    if num_failures:
      print()
      if num_failures == 1:
        print("Failed the following test:")
      else:
        print("Failed the following %d tests:" % num_failures)
      print("\t" + "\n\t".join(sorted(self.failures)))
      print()
    print('Ran %d tests in %.3fs, %d failed.' % (self.num_tests, self.took,
                                                 num_failures))
    print()


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