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

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

import os
import optparse
import subprocess
import sys

class CommandRunner(object):
  """
  Executor class for commands, including "commands" implemented by
  Python functions.
  """
  verbose = True
  active = True

  def __init__(self, dictionary={}):
    self.subst_dictionary(dictionary)

  def subst_dictionary(self, dictionary):
    self._subst_dictionary = dictionary

  def subst(self, string, dictionary=None):
    """
    Substitutes (via the format operator) the values in the specified
    dictionary into the specified command.

    The command can be an (action, string) tuple.  In all cases, we
    perform substitution on strings and don't worry if something isn't
    a string.  (It's probably a Python function to be executed.)
    """
    if dictionary is None:
      dictionary = self._subst_dictionary
    if dictionary:
      try:
        string = string % dictionary
      except TypeError:
        pass
    return string

  def display(self, command, stdout=None, stderr=None):
    if not self.verbose:
      return
    if type(command) == type(()):
      func = command[0]
      args = command[1:]
      s = '%s(%s)' % (func.__name__, ', '.join(map(repr, args)))
    if type(command) == type([]):
      # TODO:  quote arguments containing spaces
      # TODO:  handle meta characters?
      s = ' '.join(command)
    else:
      s = self.subst(command)
    if not s.endswith('\n'):
      s += '\n'
    sys.stdout.write(s)
    sys.stdout.flush()

  def execute(self, command, stdout=None, stderr=None):
    """
    Executes a single command.
    """
    if not self.active:
      return 0
    if type(command) == type(''):
      command = self.subst(command)
      cmdargs = shlex.split(command)
      if cmdargs[0] == 'cd':
         command = (os.chdir,) + tuple(cmdargs[1:])
    if type(command) == type(()):
      func = command[0]
      args = command[1:]
      return func(*args)
    else:
      if stdout is sys.stdout:
        # Same as passing sys.stdout, except python2.4 doesn't fail on it.
        subout = None
      else:
        # Open pipe for anything else so Popen works on python2.4.
        subout = subprocess.PIPE
      if stderr is sys.stderr:
        # Same as passing sys.stderr, except python2.4 doesn't fail on it.
        suberr = None
      elif stderr is None:
        # Merge with stdout if stderr isn't specified.
        suberr = subprocess.STDOUT
      else:
        # Open pipe for anything else so Popen works on python2.4.
        suberr = subprocess.PIPE
      p = subprocess.Popen(command,
                           shell=(sys.platform == 'win32'),
                           stdout=subout,
                           stderr=suberr)
      p.wait()
      if stdout is None:
        self.stdout = p.stdout.read()
      elif stdout is not sys.stdout:
        stdout.write(p.stdout.read())
      if stderr not in (None, sys.stderr):
        stderr.write(p.stderr.read())
      return p.returncode

  def run(self, command, display=None, stdout=None, stderr=None):
    """
    Runs a single command, displaying it first.
    """
    if display is None:
      display = command
    self.display(display)
    return self.execute(command, stdout, stderr)


class Unbuffered(object):
  def __init__(self, fp):
    self.fp = fp
  def write(self, arg):
    self.fp.write(arg)
    self.fp.flush()
  def __getattr__(self, attr):
    return getattr(self.fp, attr)

sys.stdout = Unbuffered(sys.stdout)
sys.stderr = Unbuffered(sys.stderr)


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):
    if '.svn' in dirs:
      dirs.remove('.svn')
    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

  usage = "gyptest.py [-ahlnq] [-f formats] [test ...]"
  parser = optparse.OptionParser(usage=usage)
  parser.add_option("-a", "--all", action="store_true",
            help="run all tests")
  parser.add_option("-C", "--chdir", action="store", default=None,
            help="chdir to the specified directory")
  parser.add_option("-f", "--format", action="store", default='',
            help="run tests with the specified formats")
  parser.add_option("-G", '--gyp_option', action="append", default=[],
            help="Add -G options to the gyp command line")
  parser.add_option("-l", "--list", action="store_true",
            help="list available tests and exit")
  parser.add_option("-n", "--no-exec", action="store_true",
            help="no execute, just print the command line")
  parser.add_option("--passed", action="store_true",
            help="report passed tests")
  parser.add_option("--path", action="append", default=[],
            help="additional $PATH directory")
  parser.add_option("-q", "--quiet", action="store_true",
            help="quiet, don't print test command lines")
  opts, args = parser.parse_args(argv[1:])

  if opts.chdir:
    os.chdir(opts.chdir)

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

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

  tests = []
  for arg in args:
    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 >>sys.stderr, arg, 'is not a valid gyp test name.'
        sys.exit(1)
      tests.append(arg)

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

  CommandRunner.verbose = not opts.quiet
  CommandRunner.active = not opts.no_exec
  cr = CommandRunner()

  os.environ['PYTHONPATH'] = os.path.abspath('test/lib')
  if not opts.quiet:
    sys.stdout.write('PYTHONPATH=%s\n' % os.environ['PYTHONPATH'])

  passed = []
  failed = []
  no_result = []

  if opts.format:
    format_list = opts.format.split(',')
  else:
    # TODO:  not duplicate this mapping from pylib/gyp/__init__.py
    format_list = {
      'aix5':     ['make'],
      'freebsd7': ['make'],
      'freebsd8': ['make'],
      'openbsd5': ['make'],
      'cygwin':   ['msvs'],
      'win32':    ['msvs', 'ninja'],
      'linux2':   ['make', 'ninja'],
      'linux3':   ['make', 'ninja'],
      'darwin':   ['make', 'ninja', 'xcode', 'xcode-ninja'],
    }[sys.platform]

  for format in format_list:
    os.environ['TESTGYP_FORMAT'] = format
    if not opts.quiet:
      sys.stdout.write('TESTGYP_FORMAT=%s\n' % format)

    gyp_options = []
    for option in opts.gyp_option:
      gyp_options += ['-G', option]
    if gyp_options and not opts.quiet:
      sys.stdout.write('Extra Gyp options: %s\n' % gyp_options)

    for test in tests:
      status = cr.run([sys.executable, test] + gyp_options,
                      stdout=sys.stdout,
                      stderr=sys.stderr)
      if status == 2:
        no_result.append(test)
      elif status:
        failed.append(test)
      else:
        passed.append(test)

  if not opts.quiet:
    def report(description, tests):
      if tests:
        if len(tests) == 1:
          sys.stdout.write("\n%s the following test:\n" % description)
        else:
          fmt = "\n%s the following %d tests:\n"
          sys.stdout.write(fmt % (description, len(tests)))
        sys.stdout.write("\t" + "\n\t".join(tests) + "\n")

    if opts.passed:
      report("Passed", passed)
    report("Failed", failed)
    report("No result from", no_result)

  if failed:
    return 1
  else:
    return 0


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