from Strategies.strat import PathFindingStrategy
from Strategies.path import restore
import heapq

class AStar(PathFindingStrategy):
    
    def heuristic(self, a, b):
        return abs(a.x - b.x) + abs(a.y - b.y)
    
    def findPath(self, maze, start, exit):
        if exit is None:
            return [], 0

        heap = []
        counter = 0
        heapq.heappush(heap, (0, counter, start))
        counter += 1
        
        parent = {}
        g = {start: 0}
        visited = set()

        while heap:
            _, _, current = heapq.heappop(heap)

            if current == exit:
                break

            visited.add(current)

            for n in maze.getNeighbors(current):
                tentative = g[current] + 1

                if n not in g or tentative < g[n]:
                    g[n] = tentative
                    priority = tentative + self.heuristic(n, exit)
                    heapq.heappush(heap, (priority, counter, n))
                    counter += 1
                    parent[n] = current

        return restore(parent, start, exit), len(visited)