from abc import ABC, abstractmethod

from cell import Cell
from maze import Maze


class MazeBuilder(ABC):

    @abstractmethod
    def build_from_file(self, filename):
        pass


class TextFileMazeBuilder(MazeBuilder):

    def build_from_file(self, filename):

        with open(filename, "r", encoding="utf-8") as file:
            lines = [line.rstrip("\n") for line in file]

        height = len(lines)
        width = len(lines[0])

        cells = []

        start = None
        exit_cell = None

        for y in range(height):

            row = []

            for x in range(width):

                symbol = lines[y][x]

                cell = Cell(x, y)

                if symbol == "#":
                    cell.is_wall = True

                elif symbol == "S":
                    cell.is_start = True
                    start = cell

                elif symbol == "E":
                    cell.is_exit = True
                    exit_cell = cell

                row.append(cell)

            cells.append(row)

        if start is None:
            raise ValueError("Start cell S not found")

        if exit_cell is None:
            raise ValueError("Exit cell E not found")        
        
        return Maze(
            cells,
            width,
            height,
            start,
            exit_cell
        )