# Bounded level-floor route planning through the public read-only environment interface.
from collections import deque
from hearth.blocks import passable


def floor_path(view, frame, start, end, area, blocked=()):
    """Find a level two-cell-high route without inferring unknown space as empty.

    Args:
        view: Public read-only environmental access.
        frame: Frame mapping all other arguments from local coordinates to world.
        start: Local standing position.
        end: Local standing position on the same floor.
        area: Inclusive local bound for standing positions.
        blocked: Prospective local occupied cells not yet submitted as effects.

    Returns:
        A deterministic local path, or an empty tuple when no path exists.
    """
    if start[1] != end[1]:
        raise ValueError('floor_path requires equal standing heights')
    blocked = set(blocked)

    def usable(p):
        head = (p[0], p[1] + 1, p[2])
        return (area.contains(p) and p not in blocked and head not in blocked and view.supports(frame.point((p[0], p[1] - 1, p[2]))) and passable(view.state(frame.point(p))) and passable(view.state(frame.point(head))))

    if not usable(start) or not usable(end):
        return ()
    parent, queue = {start: None}, deque((start,))
    while queue:
        p = queue.popleft()
        if p == end:
            result = []
            while p is not None:
                result.append(p)
                p = parent[p]
            return tuple(reversed(result))
        for dx, dz in ((0, -1), (-1, 0), (1, 0), (0, 1)):
            q = (p[0] + dx, p[1], p[2] + dz)
            if q not in parent and usable(q):
                parent[q] = p
                queue.append(q)
    return ()
