from os.path import exists


def next_path(path_pattern):
    b = get_filename_num(path_pattern)
    return path_pattern % (b + 1)


def last_path(path_pattern):
    b = get_filename_num(path_pattern)
    return path_pattern % b


def get_filename_num(path_pattern):
    """
    Finds the next free path in an sequentially named list of files

    e.g. path_pattern = 'file-%s.txt':

    file-1.txt
    file-2.txt
    file-3.txt

    Runs in log(n) time where n is the number of existing files in sequence
    """
    i = 1

    # First do an exponential search
    while exists(path_pattern % i):
        i = i * 2

    # Result lies somewhere in the interval (i/2..i]
    # We call this interval (a..b] and narrow it down until a + 1 = b
    a, b = (i // 2, i)
    while a + 1 < b:
        c = (a + b) // 2  # interval midpoint
        a, b = (c, b) if exists(path_pattern % c) else (a, c)

    return b - 1
