import re
import fnmatch


def FilterTestNames(all_tests, gtest_filter):
  """Filter a list of test names based on the given gtest filter.

  See https://github.com/google/googletest/blob/main/docs/advanced.md
  for gtest_filter specification.

  Args:
    all_tests: List of test names.
    gtest_filter: Filter to apply.

  Returns:
    Filtered subset of the given list of test names.
  """
  pattern_groups = gtest_filter.split('-')
  positive_patterns = ['*']
  if pattern_groups[0]:
    positive_patterns = pattern_groups[0].split(':')
  negative_patterns = []
  if len(pattern_groups) > 1:
    negative_patterns = pattern_groups[1].split(':')

  neg_pats = None
  if negative_patterns:
    neg_pats = re.compile('|'.join(fnmatch.translate(p) for p in
                                   negative_patterns))

  tests = []
  test_set = set()
  for pattern in positive_patterns:
    pattern_tests = [
        test for test in all_tests
        if (fnmatch.fnmatch(test, pattern)
            and not (neg_pats and neg_pats.match(test))
            and test not in test_set)]
    tests.extend(pattern_tests)
    test_set.update(pattern_tests)
  return tests