# builder.py
from abc import ABC, abstractmethod
from maze import Maze, Cell

class MazeBuilder(ABC):
    @abstractmethod
    def build_from_file(self, filename: str, require_exit: bool = True) -> Maze:
        pass

class TextFileMazeBuilder(MazeBuilder):
    def build_from_file(self, filename: str, require_exit: bool = True) -> Maze:
        with open(filename, 'r', encoding='utf-8') as f:
            lines = [line.rstrip('\n') for line in f]

        if not lines:
            raise ValueError("Файл пуст")
        height = len(lines)
        width = max(len(line) for line in lines)
        maze = Maze(width, height)

        for y, line in enumerate(lines):
            for x, ch in enumerate(line):
                if x >= width:
                    continue
                cell = maze.get_cell(x, y)
                if ch == '#':
                    cell.is_wall = True
                elif ch == 'S':
                    cell.is_start = True
                    maze.start = cell
                elif ch == 'E':
                    cell.is_exit = True
                    maze.exit = cell
        if maze.start is None:
            raise ValueError("Лабиринт должен содержать S (старт)")
        if require_exit and maze.exit is None:
            raise ValueError("Лабиринт должен содержать E (выход)")
        return maze