#!/usr/bin/env python
# Copyright 2016 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 optparse
import os
import platform
import re
import sys
import types
import traceback
import unittest


def discover(dir, filters):
  if hasattr(unittest.TestLoader, 'discover'):
    return unittest.TestLoader().discover(dir, '*')

  # poor mans unittest.discover
  loader = unittest.TestLoader()
  subsuites = []

  for (dirpath, dirnames, filenames) in os.walk(dir):
    for filename in [x for x in filenames if re.match('.*_test\.py$', x)]:
      if filename.startswith('.') or filename.startswith('_'):
        continue
      fqn = dirpath.replace(
          '/', '.') + '.' + re.match('(.+)\.py$', filename).group(1)

      # load the test
      try:
        module = __import__(fqn,fromlist=[True])
      except:
        print "While importing [%s]\n" % fqn
        traceback.print_exc()
        continue

      def test_is_selected(name):
        for f in filters:
          if re.search(f,name):
            return True
        return False

      if hasattr(module, 'suite'):
        base_suite = module.suite()
      else:
        base_suite = loader.loadTestsFromModule(module)
      new_suite = unittest.TestSuite()
      for t in base_suite:
        if isinstance(t, unittest.TestSuite):
          for i in t:
            if test_is_selected(i.id()):
              new_suite.addTest(i)
        elif isinstance(t, unittest.TestCase):
          if test_is_selected(t.id()):
            new_suite.addTest(t)
        else:
          raise Exception("Wtf, expected TestSuite or TestCase, got %s" % t)

      if new_suite.countTestCases():
        subsuites.append(new_suite)

  return unittest.TestSuite(subsuites)


def main():
  parser = optparse.OptionParser()
  parser.add_option(
      '-v', '--verbose', action='count', default=0,
      help='Increase verbosity level (repeat as needed)')
  parser.add_option('--debug', dest='debug', action='store_true', default=False,
                    help='Break into pdb when an assertion fails')
  parser.add_option('--incremental', dest='incremental', action='store_true',
                    default=False, help='Run tests one at a time.')
  parser.add_option('--stop', dest='stop_on_error', action='store_true',
                    default=False, help='Stop running tests on error.')
  (options, args) = parser.parse_args()

  if options.verbose >= 2:
    logging.basicConfig(level=logging.DEBUG)
  elif options.verbose:
    logging.basicConfig(level=logging.INFO)
  else:
    logging.basicConfig(level=logging.WARNING)

  # install hook on set_trace if --debug
  if options.debug:
    import exceptions
    class DebuggingAssertionError(exceptions.AssertionError):
      def __init__(self, *args):
        exceptions.AssertionError.__init__(self, *args)
        print "Assertion failed, entering PDB..."
        import pdb
        if hasattr(sys, '_getframe'):
          pdb.Pdb().set_trace(sys._getframe().f_back.f_back)
        else:
          pdb.set_trace()
    unittest.TestCase.failureException = DebuggingAssertionError

    def hook(*args):
      import traceback, pdb
      traceback.print_exception(*args)
      pdb.pm()
    sys.excepthook = hook

    import browser
    browser.debug_mode = True

  else:
    def hook(exc, value, tb):
      import traceback
      if not str(value).startswith("_noprint"):
        traceback.print_exception(exc, value, tb)
      import src.message_loop
      if src.message_loop.is_main_loop_running():
        if not str(value).startswith("_noprint"):
          print "Untrapped exception! Exiting message loop with exception."
        src.message_loop.quit_main_loop(quit_with_exception=True)

    sys.excepthook = hook

  # make sure cwd is the base directory!
  os.chdir(os.path.dirname(__file__))

  if len(args) > 0:
    suites = discover('trace_event_impl', args)
  else:
    suites = discover('trace_event_impl', ['.*'])

  r = unittest.TextTestRunner()
  if not options.incremental:
    res = r.run(suites)
    if res.wasSuccessful():
      return 0
    return 255
  else:
    ok = True
    for s in suites:
      if isinstance(s, unittest.TestSuite):
        for t in s:
          print '--------------------------------------------------------------'
          print 'Running %s' % str(t)
          res = r.run(t)
          if not res.wasSuccessful():
            ok = False
            if options.stop_on_error:
              break
        if ok == False and options.stop_on_error:
          break
      else:
        res = r.run(s)
        if not res.wasSuccessful():
          ok = False
          if options.stop_on_error:
            break
    if ok:
      return 0
    return 255


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