#!/usr/bin/env python
# Copyright (c) 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 inspect
import unittest
import sys
import os
import optparse

__all__ = []


def FilterSuite(suite, predicate):
  new_suite = suite.__class__()

  for x in suite:
    if isinstance(x, unittest.TestSuite):
      subsuite = FilterSuite(x, predicate)
      if subsuite.countTestCases() == 0:
        continue

      new_suite.addTest(subsuite)
      continue

    assert isinstance(x, unittest.TestCase)
    if predicate(x):
      new_suite.addTest(x)

  return new_suite


class _TestLoader(unittest.TestLoader):

  def __init__(self, *args):
    super(_TestLoader, self).__init__(*args)
    self.discover_calls = []

  def loadTestsFromModule(self, module, use_load_tests=True):
    if module.__file__ != __file__:
      return super(_TestLoader, self).loadTestsFromModule(
          module, use_load_tests)

    suite = unittest.TestSuite()
    for discover_args in self.discover_calls:
      subsuite = self.discover(*discover_args)
      suite.addTest(subsuite)
    return suite


class _RunnerImpl(unittest.TextTestRunner):

  def __init__(self, filters):
    super(_RunnerImpl, self).__init__(verbosity=2)
    self.filters = filters

  def ShouldTestRun(self, test):
    if len(self.filters) == 0:
      return True
    found = False
    for name in self.filters:
      if name in test.id():
        found = True
    return found

  def run(self, suite):
    filtered_test = FilterSuite(suite, self.ShouldTestRun)
    return super(_RunnerImpl, self).run(filtered_test)


class TestRunner(object):

  def __init__(self):
    self._loader = _TestLoader()

  def AddModule(self, module, pattern="*unittest.py"):
    assert inspect.ismodule(module)
    module_file_basename = os.path.splitext(
        os.path.basename(module.__file__))[0]
    if module_file_basename != '__init__':
      raise NotImplementedError(
          'Modules that are one file are not supported, only directories.')

    file_basename = os.path.basename(os.path.dirname(module.__file__))
    module_first_dir = module.__name__.split('.')[0]
    assert file_basename == module_first_dir, 'Module must be toplevel'

    start_dir = os.path.dirname(module.__file__)
    top_dir = os.path.normpath(
        os.path.join(os.path.dirname(module.__file__), '..'))
    self._loader.discover_calls.append((start_dir, pattern, top_dir))

  def Main(self, argv=None):
    if argv is None:
      argv = sys.argv

    parser = optparse.OptionParser()
    _, args = parser.parse_args(argv[1:])

    runner = _RunnerImpl(filters=args)
    return unittest.main(module=__name__, argv=[sys.argv[0]],
                         testLoader=self._loader,
                         testRunner=runner)
