import shutil


def check_space_requirements(new_files, changed_files, remove_files, output_path):
    """
    Given lists of new files, changed files, and files to delete, this checks that the drive these file changes
    will be made on will be able to hold all the new files.
    :param new_files: A list of new files to backup generated by mark_files().
    :param changed_files: A list of changed files to backup generated by mark_files().
    :param remove_files: A list of files to delete from the backup generated by mark_files().
    :param output_path: The path where the backup will be made.
    :return: A tuple of three values. First, true if the backup will fit on the drive, false otherwise. Second, the
             remaining free space on the target drive in bytes. This will be negative if the backup won't fit.
             Third, the difference in bytes this backup will take. This will be positive if the new backup will
             be bigger than what's already backed up, or negative if it's smaller.
    """
    total, used, free = shutil.disk_usage(output_path)
    original_free = free
    # Increase the free space on the drive for every file deleted
    for file_tuple in remove_files:
        free += file_tuple[1]
    # Decrease the free space on the drive for every new file added
    for file_tuple in new_files:
        free -= file_tuple[1]
    # Increase free space when the old changed file is deleted, then decrease for the space of the new version
    for file_tuple in changed_files:
        free = free - file_tuple[1] + file_tuple[3]
        # If free space ever dips below 0 during this, return
        if free <= 0:
            return free > 0, free, original_free - free
    return free > 0, free, original_free - free