import functools
import pprint
import util
import regen


def startswith(prefix):
    return lambda s: s.startswith(prefix)


def endswith(suffix):
    return lambda s: s.endswith(suffix)


# List of test groups. Each test group is of the following structure:
#   (NAME, (PREDICATES, TARGETS, BUILD COMMAND))
# where:
#   - NAME is a name for the group of tests. This name is used to explicitly
#     invoke this test group on the command line (e.g. fidldev test foo would
#     call fx test on the TARGETS for group foo)
#   - PREDICATES is a list of predicates P such that P(file) returns true if the
#     test group should run when |file| is changed
#   - TARGETS is a list of test names as supported by `fx test`, e.g.
#     fully-formed Fuchsia Package URLs, package names, or directories.
#   - BUILD COMMAND is any command that should be run prior to running the test
#     group. It can be None if no build step is required, and is skipped if the
#     --no-build flag is passed in. It currently needs to be a List - run_tests
#     needs to be updated to support strings
TEST_GROUPS = [
    (
        'fidlc', (
            [
                startswith('zircon/tools/fidl'),
                startswith(util.FIDL_TESTDATA_DIR),
                startswith(util.goldens_dir('fidlc')),
            ],
            [util.TEST_FIDLC, util.FIDLC_GOLDEN_TEST_TARGET],
            util.BUILD_FIDLC_TESTS)),

    # it's possible to be more selective on which changes map to which tests,
    # but since fidlgen tests are fast to build and run, just do a blanket
    # check.
    (
        'fidlgen', (
            [
                *[startswith(p) for p in util.ALL_FIDLGEN_DIRS],
                startswith(util.FIDL_TESTDATA_DIR)
            ],
            util.FIDLGEN_TEST_TARGETS, None)),
    (
        'fidldoc', (
            [startswith(util.FIDLDOC_DIR), startswith(util.FIDL_TESTDATA_DIR)],
            [util.FIDLDOC_DIR], None)),
    (
        'hlcpp', (
            [
                startswith(util.goldens_dir('fidlgen_hlcpp')),
                endswith('.tables.c.golden'),
                startswith(util.HLCPP_RUNTIME),
                startswith(util.C_RUNTIME),
            ], [util.HLCPP_TEST_TARGET], None)),
    (
        'llcpp', (
            [
                startswith(util.goldens_dir('fidlgen_llcpp')),
                endswith('.tables.c.golden'),
                startswith(util.LLCPP_RUNTIME),
                startswith(util.C_RUNTIME)
            ], [util.LLCPP_TEST_TARGET], None)),
    (
        'c',
        (
            # normally, changes to the generated bindings are detected by looking at the
            # goldens. Since we can't do this for C, we look at the coding table goldens
            # and the c_generator instead.
            [
                endswith('.tables.c.golden'),
                startswith('zircon/tools/fidl/include/fidl/c_generator.h'),
                startswith('zircon/tools/fidl/lib/c_generator.cc'),
                startswith(util.C_RUNTIME),
            ],
            # NOTE: fidl-test should also run, but this script only supports component
            # tests
            [util.C_TEST_TARGET],
            None)),
    (
        'go', (
            [
                startswith(util.goldens_dir('fidlgen_go')),
                startswith(util.GO_RUNTIME)
            ],
            util.GO_TEST_TARGETS + [util.GO_CONFORMANCE_TEST_TARGET], None)),
    (
        'rust', (
            [
                startswith(util.goldens_dir('fidlgen_rust')),
                startswith(util.RUST_RUNTIME)
            ],
            [util.RUST_TEST_TARGET], None)),
    (
        'dart', (
            [
                startswith(util.goldens_dir('fidlgen_dart')),
                startswith(util.DART_RUNTIME)
            ],
            [util.DART_TEST_TARGET], None)),
    (
        'gidl',
        (
            [startswith('tools/fidl/gidl')],
            [
                util.GIDL_TEST_TARGET,
                util.GO_CONFORMANCE_TEST_TARGET,
                util.HLCPP_CONFORMANCE_TEST_TARGET,
                util.LLCPP_CONFORMANCE_TEST_TARGET,
                util.RUST_CONFORMANCE_TEST_TARGET,
                # dart conformance is bundled into the rest of the tests
                util.DART_TEST_TARGET
            ],
            None)),
]


def test_explicit(targets):
    """ Return an explicit set of test groups """
    tests = []
    for name, test in TEST_GROUPS:
        if name in targets or 'all' in targets:
            tests.append(test)
    return tests


def test_changed(changed_files):
    """ Return relevant test groups given a set of changed files """
    tests = []
    for _, test in TEST_GROUPS:
        (predicates, _, _) = test
        for file_ in changed_files:
            if any(p(file_) for p in predicates):
                tests.append(test)
    return tests


def run_tests(tests, dry_run, interactive, fx_test_args, gtest_filter):
    already_built = set()
    test_targets = set()
    test_fidlc = False
    for name, targets, build in tests:
        if build is not None and tuple(build) not in already_built:
            already_built.add(tuple(build))
            util.run(build, dry_run, exit_on_failure=True)

        for target in targets:
            if target == util.TEST_FIDLC:
                test_fidlc = True
            else:
                test_targets.add(target)

    test_targets = list(test_targets)
    if interactive:
        print('all tests: ')
        if test_fidlc:
            print(util.TEST_FIDLC)
        pprint.pprint(test_targets)

        if test_fidlc:
            if input('run {}? (Y/n)'.format(util.TEST_FIDLC)) == 'n':
                test_fidlc = False
        test_targets = interactive_filter(test_targets)

    test_targets.sort()

    success = True
    if test_fidlc:
        cmd = util.TEST_FIDLC
        if gtest_filter:
            cmd += f' --gtest_filter={gtest_filter}'
        success = success and util.run(cmd, dry_run)
        # print test line that can be copied into a commit message
        # the absolute FUCHSIA_DIR paths are stripped for readability and
        # because they are user specific
        print('Test: ' + cmd.replace(str(util.FUCHSIA_DIR) + '/', ''))

    if test_targets:
        cmd = ['fx', 'test'] + fx_test_args.split()
        # group all tests into a single `fx test` invocation so that the summary
        # prints all results
        cmd.extend(test_targets)
        success = success and util.run(cmd, dry_run)
        print('Test: ' + ' '.join(cmd))

    return success


def interactive_filter(test_targets):
    if not test_targets:
        return []
    filtered = []
    for test in test_targets:
        if input('run {}? (Y/n) '.format(test)) == 'n':
            continue
        filtered.append(test)
    return filtered
