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.HLCPP_HOST_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
