from typing import Dict
from typing import Set
from typing import List


def determine_test_candidates(
    tests_dependency_graph: Dict[str, Set[str]],
    relevant_source_files: List[str],
    changed_test_files: List[str],
) -> List[str]:
    """Determines a list of test files that should be run to cover a set of changed source files

    These are the raw results and will need to undergo further processing before a finalized
    list can be provided to the user.

    Args:
        tests_dependency_graph: A mapping between source files and the relevant test files needed to gain coverage (see `parse_pytest_tests_from_codebase`)
        relevant_source_files: The output list of source files determined by `determine_relevant_source_files`
        changed_test_files: A colleciton of test files that are relevant to the current commit/PR

    Returns:
        A list of test file candidates that will possibly be part of the final output

    """
    # Ensure we include any test files that were identified in the git diff
    candidates = {file for file in changed_test_files}

    for file in relevant_source_files:
        tests: Set[str] = tests_dependency_graph.get(file, set())
        for test in tests:
            candidates.add(test)
    return sorted(candidates)